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