有没有办法为整个代码块更改数据库。例如:
with using_db('my_other_db_conf'):
MyModel.objects.all()
相当于:
MyModel.objects.using('my_other_db_conf').all()
我只需要根据上下文使用不同的数据库,并且不喜欢每次使用 using()方法的想法:\
答案 0 :(得分: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作为默认管理器,只需将其重命名为对象
答案 1 :(得分: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比隐式更好,只需安排你的代码并将共享相同db的查询集包含在函数调用中,就会更好。