0

コード ブロック全体のデータベースを変更する方法はありますか。例えば:

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

これは次と同等です:

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

コンテキストに応じて異なる DB を使用する必要があるだけで、毎回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(...)

明示的は暗黙的よりも優れていることに注意してください。コードを配置し、同じデータベースを共有するクエリセットを関数呼び出しに囲むだけでよいでしょう。

于 2012-04-12T09:50:49.043 に答える