我可以轻松地超越Django ORM' iexact'使用LOWER()而不是UPPER()?

时间:2012-01-26 20:47:09

标签: django postgresql django-orm

使用Django 1.3x。

我目前有一个非常非常非常非常活跃的Postgres数据集,其中有一个重要的列索引为lower(column)

我刚刚意识到一些常见的查询非常慢,因为当我使用blah = UPPER(column)匹配该字段时,Django ORM正在为该字段生成iexact的查询。

是否有一种简单的方法可以强制ORM使用lower(),或者我是否需要使用原始SQL进行此操作?

谢谢!

[评论的另一个问题:在指数上使用upper()而不是lower(),是否有充分的理由被忽略?]

2 个答案:

答案 0 :(得分:7)

这里有趣的情况。我以前从来没有真正停下来想过这件事。似乎UPPER用于iexact搜索的问题在revision 8536中被引入,以回应近三年前的ticket 3575。在此之前,Django一直在使用ILIKE进行这些类型的搜索。

我查看了后端代码,我发现的唯一可以指出UPPER vs LOWER的任何原因似乎是Oracle在处理不区分大小写的数据时默认为大写。由于其他人是不可知的,似乎Django决定默认为UPPER以涵盖所有基础。

我从查看源代码得到的另一个印象是,您不会使用UPPER。它实际上遍布整个地方,而不仅仅是在实际查询数据库时。 Python的upper字符串扩展也经常使用。

我想说你最好的办法就是简单地用upper(column)创建一个索引,或者代替,然后去喝一杯。

答案 1 :(得分:3)

在转到.raw()

之前尝试.extra()
MyModel.objects.extra(where=["lower(mycol)=%s"], params=['foo'])