0

有没有办法为整个代码块更改数据库。例如:

with using_db('my_other_db_conf'):
    MyModel.objects.all()

这相当于:

MyModel.objects.using('my_other_db_conf').all()

我只需要根据上下文使用不同的数据库,并且不喜欢每次都使用using()方法的想法:\

4

2 回答 2

0

我会使用经理。在你的 models.py 中:

class DB_one_ItemsManager(models.Manager):
    def get_query_set(self):
        return super(DB_one_ItemsManager, self).get_query_set().using("database1")

class DB_two_ItemsManager(models.Manager):
    def get_query_set(self):
        return super(DB_two_ItemsManager, self).get_query_set().using("database2")

class YourModel(models.Model):    
    #Some fields here
    #...

    objects_db_one=DB_one_ItemsManager()
    objects_db_two=DB_two_ItemsManager()

或者,如果您想使用 objects_db_one 或 objects_db_two 作为默认管理器,只需将其重命名为 objects

于 2012-04-12T07:25:14.213 回答
0

行为需要修改一些全局值,IMO,因此with statement不是合适的方式。当然,它可以以一种隐式的、肮脏的和线程不安全的方式来完成:

from contextlib import contextmanager 
@contextmanager 
def unsafe_modify_queryset_db(model_dbs): 
    """model_dbs => sequence of tuple (model, db for the model to use).

    For example ((User, 'slice_2'), ...) 
    """ 
    prev_db = map(lambda x:x[0].objects._db , model_dbs) 
    for model, db in model_dbs: 
        model.objects._db = db 
    yield 
    # restore previous db 
    for x, db in zip(model_dbs, prev_db): 
        x[0].objects._db = prev_db 

# then
with unsafe_modify_queryset_db((User, 'slice_2', ...)):
    User.objects.filter(...)

也可以使用db_manager对 QuerySet 级别进行操作,达到与 luke14free 的代码相同的目的:

qs = User.objects.db_manager('slice_2')
foo = qs.filter(...)
bar = qs.filter(...)

请记住,Explicit 比 implicit 更好,只需安排您的代码并将共享相同数据库的查询集附在函数调用中,会更好。

于 2012-04-12T09:50:49.043 回答