手动为QuerySet选择数据库会覆盖Django中的数据库路由器方法吗?

时间:2017-01-30 20:05:48

标签: django database

我正在使用django 1.8,我想定义两个数据库,但我想很少使用其中一个。

所以我定义了两个数据库和一个这样的默认路由器:

DATABASES = { 
    'default': {
        'ENGINE': '...',
        ...
    },  
    'secondary': {
        'ENGINE': '...',
        ...
    }   
}
DATABASE_ROUTERS = ['DefaultRouter']

然后像这样定义DefaultRouter,这样migrate就不会对它产生任何影响:

DEFAULT = 'default'
class DefaultRouter(object):
    def db_for_read(self, model, **hints):
        """Reads go to 'default'
        """
        return DEFAULT

    def db_for_write(self, model, **hints):
        """Writes always go to 'default'
        """
        return DEFAULT

    def allow_relation(self, obj1, obj2, **hints):
        """ Relations between objects are allowed if both objects are in the 'default' pool.
        """
        if obj1._state.db == DEFAULT and obj2._state.db == DEFAULT:
            return True
        return False

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if db == DEFAULT:
            return True
        else:   
            return False

假设我有一个名为Model的{​​{1}},它存在于具有不同实例的两个数据库中。我想从我的Book数据库对Book进行查询,如下所示: secondary

我现在有两个问题:

1-此查询是否会在路由器中使用该方法命中books = Book.objects.using('secondary').filter(author="john")数据库,以便将所有读/写路由到secondary?更一般地说:default会覆盖路由器的方法吗?

2- using(),是否可以安全地拨打book = books.first()?安全我的意思是它命中book.author数据库。或者我必须使用secondary来访问该对象字段?

1 个答案:

答案 0 :(得分:1)

  1. Refer to Django Docs Multi DBs
  2.   

    Django还提供了一个API,允许您在代码中保持对数据库使用的完全控制。手动指定的数据库分配优先于路由器分配的数据库。

    1. Django过滤器被懒惰地评估,所以在你运行book.author之前,book将包含对Book.objects.using('secondary').filter(author="john").first()的引用,因此它将来自辅助数据库。
    2. 但是您可能也想检查一下: 的 Save on Multi DBs

        

      如果您已将实例保存到一个数据库,则可能很想使用save(using = ...)作为将实例迁移到新数据库的方法。但是,如果您没有采取适当的措施,可能会产生一些意想不到的后果。