![](/img/trans.png)
[英]Django - objects.values() and prefetch_related() in same query
[英]Django: Database used for prefetch_related is not the same that the parent query
我在我的 Django 應用程序中使用了一個多數據庫和一個主數據庫和一個只讀副本,但為了避免復制滯后問題,路由器總是使用默認數據庫,除了我手動設置數據庫的少數地方。
我面臨一個問題,因為我不知道如何指定用於 prefetch_related 的數據庫。
例如,我希望下一個查詢僅使用read_replica
DB,但它執行 2 個查詢,第一個按預期轉到read_replica
,第二個轉到default
DB。
users = UserProfile.objects.using('read_replica').prefetch_related('usermedia_set').filter(id__in=user_ids)
這是此查詢的輸出:
選擇@@SQL_AUTO_IS_NULL; 參數=無
選擇版本(); 參數=無
SELECT ... FROM
ftmanager_userprofile
WHERE(ftmanager_userprofile
。id
IN(33); ARGS =(33,)選擇@@SQL_AUTO_IS_NULL; 參數=無
選擇版本(); 參數=無
SELECT ... FROM
ftmanager_usermedia
WHEREftmanager_usermedia
。user_id
輸入 (33); 參數=(33,)
我在Django票證上看到了相關票證,但我不明白如何將using()
應用於內部查詢集。
我找到了考慮 Django 票證的解決方案,您需要使用Prefetch
類來定義 prefetch_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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.