为了测试目的,如何在初始查询期间自动获取未在select_related()调用中指定的相关表,以防止Django?
我有一个很大的应用程序,我大量使用 select_related()在每个原始文件中引入相关的模型数据 查询。所有select_related()调用都用于指定特定的相关模型,而不是依赖于默认值,例如: select_related('foo','bar','foo__bar')
随着应用程序的增长,select_related调用没有 完全跟上,让Django愉快地留下了许多场景 并亲切地跑到数据库来获取相关的模型 行。这显着增加了数据库命中的数量 我显然不想要。
通过查看查询,我在跟踪这些方面取得了一些成功 使用django.db.connection.queries集合生成,但有些 仍未解决。
我试图在django代码中找到合适的补丁位置来引发 在这种情况下的异常,使跟踪更容易,但倾向于 迷失在代码中。
感谢。
答案 0 :(得分:1)
经过多次挖掘后,我在代码中找到了这样做的地方。
有问题的文件是django / db / models / fields / related.py
您需要在此文件中插入两行。
找到类“SingleRelatedObjectDescriptor”。您需要更改函数__get __(),如下所示:
def __get__(self, instance, instance_type=None):
if instance is None:
return self
try:
return getattr(instance, self.cache_name)
except AttributeError:
raise Exception("Automated Database Fetch on %s.%s" % (instance._meta.object_name, self.related.get_accessor_name()))
# leave the old code here for when you revert!
类似地,在代码中的“ReverseSingleRelatedObjectDescriptor”类中,您再次需要将__get __()更改为:
def __get__(self, instance, instance_type=None):
if instance is None:
return self
cache_name = self.field.get_cache_name()
try:
return getattr(instance, cache_name)
except AttributeError:
raise Exception("Automated Database Fetch on %s.%s" % (instance._meta.object_name, self.field.name))
# BEWARE: % parameters are different to previous class
# leave old code here for when you revert
完成此操作后,您会发现Django每次执行自动数据库查找时都会引发异常。当你第一次启动时,这非常烦人,但它将帮助你追踪那些讨厌的数据库查找。显然,当你找到它们时,最好将数据库代码恢复正常。我只建议在调试/性能调查阶段使用它而不是实时生产代码!
答案 1 :(得分:0)
那么,你问的是如何阻止一种方法去做它专门设计的方法呢?我不明白你为什么要那样做。
但是,关于select_related的一件事是,它不会自动遵循定义为null=True
的关系。因此,如果您现在可以将FK设置为,则不会遵循关系。