代码之家  ›  专栏  ›  技术社区  ›  caot

如何使用给定的数据库在django中的方法内进行查询?

  •  0
  • caot  · 技术社区  · 8 年前

    就是这个案子。方法或函数有两个数据库查询。有两个数据库,例如 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 回复  |  直到 8 年前
        1
  •  1
  •   marcanuy    8 年前

    如中所述 Multiple databases 文档:

    您可以在数据库中的任意点选择查询集的数据库。 queryset'chain. 使用指定数据库的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()
    
        2
  •  0
  •   caot    8 年前

    Django, Databases, and Decorators 有一个解决方案使用 django DATABASE_ROUTERS .

    Here 你可以从中找到一个例子 docs.djangoproject.com . 下面是来自“django,databases,and decorators”的摘要:

    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']
    

    三。下面是如何使用它

    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()
    
    推荐文章