Django - 防止自动相关的表获取

时间:2011-02-18 15:25:42

标签: django

为了测试目的,如何在初始查询期间自动获取未在select_related()调用中指定的相关表,以防止Django?

我有一个很大的应用程序,我大量使用 select_related()在每个原始文件中引入相关的模型数据 查询。所有select_related()调用都用于指定特定的相关模型,而不是依赖于默认值,例如: select_related('foo','bar','foo__bar')

随着应用程序的增长,select_related调用没有 完全跟上,让Django愉快地留下了许多场景 并亲切地跑到数据库来获取相关的模型 行。这显着增加了数据库命中的数量 我显然不想要。

通过查看查询,我在跟踪这些方面取得了一些成功 使用django.db.connection.queries集合生成,但有些 仍未解决。

我试图在django代码中找到合适的补丁位置来引发 在这种情况下的异常,使跟踪更容易,但倾向于 迷失在代码中。

感谢。

2 个答案:

答案 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设置为​​,则不会遵循关系。