Мультитенантные приложения Django: изменение подключения к базе данных по запросу?
Я ищу рабочий код и идеи от других, кто пытался создать мультитенантное приложение Django, используя изоляцию на уровне базы данных.
Обновление / Решение: Я закончил решение этого в новом проекте с открытым исходным кодом: см.Джанго-дб-Многоквартирный
ЦельМоя цель состоит в том, чтобы мультиплексировать запросы по мере их поступления на один сервер приложений (интерфейс WSGI, такой как gunicorn), основываясь на имени хоста или пути запроса (например,foo.example.com/
устанавливает соединение Django для использования базы данныхfoo
, а такжеbar.example.com/
использует базу данныхbar
).
Мне известно о нескольких существующих решениях для мульти-аренды в Джанго:
Джанго-арендатор-схем: Это очень близко к тому, что я хочу: вы устанавливаете промежуточное программное обеспечение с наивысшим приоритетом, и он отправляетSET search_path
Команда в БД. К сожалению, это специфично для Postgres, и я застрял с MySQL.Джанго-простой Многоквартирный: Стратегия здесь заключается в том, чтобы добавить "арендатор» внешний ключ ко всем моделям и настройте всю бизнес-логику приложения, чтобы отключить ее. В основном каждая строка индексируется(id, tenant_id)
скорее, чем(id)
, Я'мы пытались, и неЭтот подход нравится по ряду причин: он делает приложение более сложным, может приводить к трудно обнаруживаемым ошибкам и не обеспечивает изоляции на уровне базы данных.Один {сервер приложений, файл настроек django с соответствующей базой данных} для каждого клиента. Ака беднягас несколькими арендаторами (на самом деле богатый человекс учетом имеющихся ресурсов). Я не хочу раскручивать новый сервер приложений для каждого клиента, а для масштабируемости я хочу, чтобы любой сервер приложений мог отправлять запросы любому клиенту.идеиМоя лучшая идея на данный момент - сделать что-то вродеdjango-tenant-schemas
: в первом промежуточном программном обеспечении, захватитьdjango.db.connection
и играть с выбором базы данных, а не схемы. У меня нетне совсем продумал, что это значит с точки зрения объединенных / постоянных соединений
Еще одним тупиком, который я преследовал, были специфичные для арендатора префиксы таблиц: откладываяМне нужно, чтобы они были динамическими, даже глобальный префикс таблиц не так легко получить в Django (см.отклоненный билет 5000среди прочих).
Наконец, Джангоподдержка нескольких баз данных позволяет вам определить несколько именованных баз данных и мультиплексирование между ними на основе типа экземпляра и режима чтения / записи. Бесполезно, так как нет возможности выбрать базу данных для каждого запроса.
ВопросКому-нибудь удалось что-нибудь подобное? Если да, то как вы это реализовали?