Несколько mongoDB, связанных с одним и тем же django отдыхом рамочного проекта

У нас есть один проект django rest Framework (DRF), который должен иметь несколько баз данных (mongoDB). Каждая база данных должна быть независимой. Мы можем подключиться к одной базе данных, но когда мы собираемся в другую БД для записи, происходит соединение, но данные сохраняются в БД, которая сначала подключается. Мы изменили БД по умолчанию и все, но без изменений.

(Примечание: решение должно быть подходящим для использования сериализатора. Потому что нам нужно использовать DynamicDocumentSerializer в DRF-mongoengine.

Заранее спасибо.

2 ответа

Я думаю, я наконец-то получил то, что вам нужно.

Что вы можете сделать, это написать действительно простое промежуточное ПО, которое отображает вашу схему URL в базу данных:

from mongoengine import *


class DBSwitchMiddleware:
   """
   This middleware is supposed to switch the database depending on request URL.
   """
    def __init__(self, get_response):
        # list all the mongoengine Documents in your project
        import models
        self.documents = [item for in dir(models) if isinstance(item, Document)]

    def __call__(self, request):
        # depending on the URL, switch documents to appropriate database
        if request.path.startswith('/main/project1'):
             for document in self.documents:
                 document.cls._meta['db_alias'] = 'db1'
        elif request.path.startswith('/main/project2'):
             for document in self.documents:
                 document.cls._meta['db_alias'] = 'db2'

        # delegate handling the rest of response to your views
        response = get_response(request)

        return response

Обратите внимание, что это решение может быть подвержено гонкам. Здесь мы модифицируем документы глобально, поэтому, если один запрос был запущен, а затем в середине его выполнения второй запрос обрабатывается тем же интерпретатором Python, он будет перезаписан document.cls._meta['db_alias'] Установка и первый запрос начнут запись в ту же базу данных, что ужасно сломает вашу базу данных.

Один и тот же интерпретатор python используется двумя обработчиками запросов, если вы используете многопоточность. Таким образом, с этим решением вы не можете запустить свой сервер с несколькими потоками, только с несколькими процессами.

Чтобы решить проблемы с потоками, вы можете использовать threading.local (). Если вы предпочитаете подход контекстного менеджера, есть также модуль contextvars.

Во время бега connect() просто назначьте псевдоним для каждой из ваших баз данных, а затем для каждого документа укажите параметр db_alias в meta который указывает на конкретный псевдоним базы данных:

settings.py:

from mongoengine import connect


connect(
    alias='user-db',
    db='test',
    username='user',
    password='12345',
    host='mongodb://admin:qwerty@localhost/production'
)

connect(
    alias='book-db'
    db='test',
    username='user',
    password='12345',
    host='mongodb://admin:qwerty@localhost/production'
)

models.py:

from mongoengine import Document


class User(Document):
    name = StringField()

    meta = {'db_alias': 'user-db'}

class Book(Document):
    name = StringField()

    meta = {'db_alias': 'book-db'}
Другие вопросы по тегам