簡體   English   中英

如何使用給定的數據庫在Django的方法內進行查詢?

[英]How to use a given database to make queries within a method in django?

就是這種情況。 方法或函數具有幾個數據庫查詢。 有兩個數據庫,例如DATABASE_ADATABASE_B

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

如何使用decoratorany other ways輕松實現以下目標? 誰能舉一個example model.objects.using(some database)是一種已知方法,但是該方法中有很多查詢。 我不想碰它們,所以這不是一個選擇。

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

如在多個數據庫文檔中指定的:

您可以在QuerySet“鏈”中的任何位置選擇QuerySet的數據庫。只需在QuerySet上調用using()即可獲得另一個使用指定數據庫的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()

Django,數據庫和裝飾器具有使用django DATABASE_ROUTERS的解決方案。

在這里,您可以從docs.djangoproject.com找到一個示例。 以下是“ Django,數據庫和裝飾器”的摘要:

1.編寫自定義裝飾器

這里將decorator decorators.py命名為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.更新設置

這是settings.pyDATABASES示例:

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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM