Как использовать данную базу данных для выполнения запросов в методе в Django? - PullRequest
0 голосов
/ 08 июня 2018

Вот случай.У метода или функции есть пара запросов к базе данных.Есть две базы данных, такие как DATABASE_A и DATABASE_B.

def method():
    # database queries here
    orders = Order.objects.filter(...)
    products = Product.objects.filter(...)

Как легко добиться следующих результатов с помощью decorator или any other ways?Кто-нибудь может дать example?model.objects.using(some database) - известный способ, однако в методе много запросов.Я не хочу их трогать, так что это не вариант.

# Here call method() using DATABASE_A
# here call method() using DATABASE_B

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Django, базы данных и декораторы имеет решение, использующее django DATABASE_ROUTERS .

Здесь вы можете найти пример из docs.djangoproject.com .Ниже приводится краткое изложение «Джанго, базы данных и декораторы»:

1.Написание пользовательского декоратора

Здесь назовите decorator как decorators.py:

from functools import wraps

try:
    from threading import local
except ImportError:
    from _threading_local import local

threadlocal = local()


class use_db_for_reads(object):

    def __init__(self, database_name):
        self.database_name = database_name

    def __enter__(self):
        setattr(threadlocal, 'DB_FOR_READ_ONLY', self.database_name)

    def __exit__(self, exc_type, exc_value, traceback):
        setattr(threadlocal, 'DB_FOR_READ_ONLY', None)

    def __call__(self, test_func):
        @wraps(test_func)
        def inner(*args, **kwargs):
            return test_func(*args, **kwargs)
        return inner


def get_thread_local(attr, default=None):
    return getattr(threadlocal, attr, default)


class AnalyticsRouter(object):

    def db_for_read(self, model, **hints):
        return get_thread_local('DB_FOR_READ_ONLY', 'default')

    def db_for_write(self, model, **hints):
        return 'default'

    def allow_relation(self, obj1, obj2, **hints):
        return True

2.обновить настройки

Вот пример DATABASES в settings.py:

DATABASES = {
    'default': {
        ...
    },
    'read-only': {
        ...
    }
}

DATABASE_ROUTERS = ['decorators.AnalyticsRouter']

3.Вот как это использовать

from decorators import use_db_for_reads

# Here call method() using DATABASE_A
with use_db_for_reads(DATABASE_A):
    method()

# here call method() using DATABASE_B
with use_db_for_reads(DATABASE_B):
    method()
0 голосов
/ 08 июня 2018

Как указано в Несколько баз данных документы:

Вы можете выбрать базу данных для QuerySet в любой точке цепочки QuerySet. Просто позвоните с помощью () наQuerySet для получения другого QuerySet, который использует указанную базу данных.

>>> # This will run on the 'default' database.
>>> Author.objects.all()

>>> # So will this.
>>> Author.objects.using('default').all()

>>> # This will run on the 'other' database.
>>> Author.objects.using('other').all()
...