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