Python Django:用于预回迁的数据库与父查询不同
我在Django应用程序中使用了一个多数据库,其中包含一个主数据库和一个读取副本,但为了避免复制延迟问题,路由器总是使用默认数据库,只有少数地方我手动设置了数据库 我面临一个问题,因为我不知道如何指定用于预回迁的数据库 例如,我希望下一个查询只使用Python Django:用于预回迁的数据库与父查询不同,python,django,orm,database-replication,Python,Django,Orm,Database Replication,我在Django应用程序中使用了一个多数据库,其中包含一个主数据库和一个读取副本,但为了避免复制延迟问题,路由器总是使用默认数据库,只有少数地方我手动设置了数据库 我面临一个问题,因为我不知道如何指定用于预回迁的数据库 例如,我希望下一个查询只使用read\u replicaDB,但它执行两个查询,第一个查询按预期转到read\u replica,第二个查询转到defaultDB users = UserProfile.objects.using('read_replica').prefetch
read\u replica
DB,但它执行两个查询,第一个查询按预期转到read\u replica
,第二个查询转到default
DB
users = UserProfile.objects.using('read_replica').prefetch_related('usermedia_set').filter(id__in=user_ids)
这是此查询的输出:
选择@@SQL\u AUTO\u为空;args=None
选择版本();args=None
选择。。。从(33)中的ftmanager\u userprofile
位置(ftmanager\u userprofile
id
;args=(33,)
选择@@SQL\u AUTO\u为空;args=None
选择版本();args=None
从(33)中的ftmanager\u usermedia
WHEREftmanager\u usermedia
user\u id
;args=(33,)
我在上看到一个相关的票证,但我不知道如何将
using()
应用到内部查询集。我找到了解决方案,考虑到Django票证,您需要使用Prefetch
类来定义Prefetch\u related使用的内部查询集,它确实会弄乱代码,但收益是值得的:
from django.db.models.query import Prefetch
users = UserProfile.objects.using('read_replica').prefetch_related(Prefetch('usermedia_set', queryset=UserMedia.objects.using('read_replica'))).filter(id__in=user_ids)
我也遇到了同样的问题。配置路由器(即db_for_read和使用提示中的实例)有助于:
def db_for_read(self, model, **hints):
instance = hints.get('instance')
if instance is not None:
if instance._meta.app_label in self.route_app_labels:
return self.route_db_name
elif model._meta.app_label in self.route_app_labels:
return self.route_db_name