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

Сценарий

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

TheApp

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

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

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

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

Вопрос

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

Ответы, которые я придумал ™

Я читаю материал, и вот способы, которыми я придумал:

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

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

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

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

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

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

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

Один settings.py + Маршрутизатор приложений

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

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

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

Некоторые неясны по-другому

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

Почему бы не все в одном дБ?

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

Ответы [ 2 ]

2 голосов
/ 23 марта 2012

Это легко сделать с помощью промежуточного программного обеспечения и пространств имен 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, чтобы игнорировать описанную выше процедуру if settings.EBUG - True, но вы также можете настроить виртуальные хосты и отредактировать файл hosts, чтобы проверить это в разработке.
  2. Еще одно соображение заключается в том, что вы должны запуститьотдельный виртуальный хост для каждого экземпляра.В противном случае вы можете столкнуться с проблемами, когда данные экземпляра могут пересекаться.Я предполагаю, что это какая-то проблема с многопоточностью, но кто-то умнее, чем я, может объяснить это более подробно.
  3. Наконец, вам нужно подумать о том, как справляться с новыми установками и обновлениями схемы.Джанго поместит все в публичную схему.Вам нужно будет научиться копировать эту схему для создания новой, а также привыкнуть к сценариям обновлений баз данных.
1 голос
/ 02 ноября 2011

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

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

  • использовать промежуточное ПО для сохранения конфигурации пользователя в некоторой структуре данных (поддерживается django)
  • сделать настройки. БАЗА ДАННЫХ может вызывать конфигурацию пользователей сверху (django hack)
  • использовать функцию множественной базы данных django для доступа к моделям (поддерживается django)
...