Как использовать другую базу данных на «экземпляр приложения» в Django?

Сценарий

У нас есть два приложения.

Приложение

TheApp – невероятное приложение, которое любят клиенты. Каждый клиент получает свой экземпляр приложения, что означает, что каждый клиент будет использовать другую базу данных (имя, пользователь, пароль). Соединение с базой данных должно быть определено в домене, из которого поступает запрос.

req: customerA.foo.tld -> db:(app_cust1, cust1, hunter2) req: customerB.foo.tld -> db:(app_cust2, cust2, hunter3) 

Администрирование приложения

Должен иметь возможность создавать / удалять экземпляры TheApp для клиентов. Поэтому он должен настроить новую базу данных и записать конфигурацию где-нибудь . Способ, который определяет, какой db используется для входящего запроса, должен хорошо работать и быть легко управляемым.

Вопрос

Каков наилучший способ решить, какое соединение с базой данных должно использоваться для экземпляра? Что работает лучше всего? Какие весы лучше всего?

Ответы Я придумал ™

Я читал материал, и это то, как я придумал:

(wsgi daemon + settings.py) на экземпляр

Каждый клиент получит свои собственные settings.py с учетными данными базы данных. Настройки могут наследовать некоторые общие вещи из файла общих настроек.

Для каждого нового файла настроек должен быть запущен новый экземпляр wsgi приложения. Это может сильно ухудшиться, если у нас много клиентов? Также создание apache vhost файлов является уродливым.

Использование 'using' и one settings.py

Я мог бы сделать это, как

 MyModel.objects.using(THE_CURRENT_DB).all() 

и установите THE_CURRENT_DB где-нибудь (промежуточное ПО?) за запрос. Но, похоже, уродство нужно делать везде. Также settings.py/app нужно переписывать каждый раз, когда клиент получает свой экземпляр.

Один параметр setup.py + Application Router

Я еще не посмотрел, могу ли я получить доступ к любой информации о запросе в маршрутизаторе, но если это так, я, возможно, могу решить, какой из dbs в settings.py следует использовать. Например, https://docs.djangoproject.com/en/1.3/topics/db/multi-db/#an-example, но не для каждой модели, а для каждого запроса.

Изменение настроек в промежуточном программном обеспечении

Просто была идея, что, возможно, настройка db может быть изменена в промежуточном программном обеспечении. Еще не посмотрел, как работает промежуточное программное обеспечение в Django и что там возможно.

Некоторый неясный другой путь

Поскольку я довольно новичок в Django, я, возможно, пропустил некоторые моменты, или некоторые из них просто совершенно глупы и плохи. Что бы вы сделали?

Почему не все в одном db?

Что ж. Потому что я думаю, что разделение вещей хорошее. И если плохие вещи случаются, не все внезапно оказываются затронутыми.

2 Solutions collect form web for “Как использовать другую базу данных на «экземпляр приложения» в Django?”

Это один из тех сценариев, которые показывают слабость модуля конфигурации django (настройки). Нет никакого способа, поддерживаемого django.

Я думаю, вы можете выбрать вариант с минимальным воздействием на обслуживание и переносимость кода. Поэтому я предлагаю:

  • используйте промежуточное программное обеспечение, чтобы сохранить конфигурацию пользователей в некоторой структуре данных (поддерживается django)
  • make settings.DATABASE можно использовать для настройки конфигурации пользователей сверху (django hack)
  • использовать функцию множественной базы данных django для доступа к моделям (поддерживается django)

Это легко сделать с помощью промежуточного слоя и пространств имен Postgres. Вот быстрый и грязный пример без обработки ошибок:

 class NamespaceMiddleware: def process_request(self, request): # Get the subdomain. You could also use the domain name, but you'll have to remove special characters. host = request.get_host() parts = host.split('.') if len(parts) >= 3: subdomain = parts[0] # Set the namespace (aka "schema"). This will throw a DatabaseError if the namespace does not exist. from django.db import connection cursor = connection.cursor() cursor.execute("SET search_path TO ", subdomain) 

Благодаря этому промежуточному программному обеспечению каждый клиент может иметь полностью отдельные данные, и для его работы не требуется монополия. Однако есть несколько вещей, которые нужно знать:

  1. Одна из проблем связана с этим в развитии. Обычно я добавляю оператор if, чтобы игнорировать описанную выше процедуру, если settings.DEBUG имеет значение True, но вы также можете настроить виртуальные хосты и отредактировать файл hosts, чтобы проверить это в процессе разработки.
  2. Другое соображение заключается в том, что для каждого экземпляра необходимо запустить отдельный виртуальный хост. В противном случае вы можете столкнуться с проблемами, когда данные экземпляра могут пересекаться. Я предполагаю, что это какая-то проблема с потоками, но кто-то умнее, чем я могу объяснить это более подробно.
  3. Наконец, вам нужно подумать о том, как справляться с новыми обновлениями установки и схемы. Django поместит все в общедоступную схему. Вам нужно научиться копировать эту схему, чтобы создать новую, а также привыкнуть к созданию сценариев обновлений баз.
  • Добавление поля ManyToManyField к существующей модели
  • Как избавиться от фиктивного выбора, созданного RadioSelect of Django Form
  • Как согласовать два столбца таблицы django model
  • Лучший способ ссылки на модель пользователя в Django> = 1.5
  • Скрипт Django для доступа к объектам модели без использования оболочки manage.py
  • Как отправить электронную почту через Django?
  • Необязательно получить параметры в django?
  • AttributeError: объект «Nonetype» не имеет атрибута «_info»
  • Как открыть туннель SSH с помощью python?
  • Ошибка в интерактивной оболочке django на eclipse pydev
  • Django вызывает сохранение объекта QuerySet - объект QuerySet не имеет атрибута «save»
  • Python - лучший язык программирования в мире.