Несколько mongoDB, связанных с одним и тем же django отдыхом рамочного проекта - PullRequest
0 голосов
/ 14 февраля 2019

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

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

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

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Наверное, я наконец-то получил то, что тебе нужно.

Что вы можете сделать, так это написать действительно простое промежуточное ПО, которое отображает вашу схему 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 .

0 голосов
/ 19 февраля 2019

Во время работы 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'}
...