簡體   English   中英

Django:用於 prefetch_related 的數據庫與父查詢不同

[英]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_userprofileid IN(33); ARGS =(33,)

選擇@@SQL_AUTO_IS_NULL; 參數=無

選擇版本(); 參數=無

SELECT ... FROM ftmanager_usermedia WHERE ftmanager_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM