我有一个包含2个字段的简单模型:
class Simple(Model)
class Meta:
index_together = True
a = IntField()
b = IntField()
我想为a,b
的值元组生成SQL查询。
e.g。
select *
from SimpleModel
where (a,b) in ((1,1), (4,8), ...)
我知道如何创建类似的东西:
select *
from SimpleModel
where ((a = 1 and b = 1) or (a = 4 and b = 8))
这在逻辑上是相同的,但我认为我的数据库在可能值的数量非常大(我使用Postgresql)时有问题,查询本身也要长得多,所以它在网络上更重,并且可能更难以正确地分析和读取它(即在这种情况下使用复合索引)。
所以,问题是,我可以让Django以第一种形式创建查询吗?
谢谢!
答案 0 :(得分:6)
@Wolph答案是正确的,但我会这样做
tuple_of_tuples = ((1,1), (4,8))
Simple.objects.extra(where=['(a,b) in %s'], params=[tuple_of_tuples])
点击此处查看有关传递元组而不是列表的信息
Passing lists or tuples as arguments in django raw sql
对于我引用Django文档的params
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra
<强> PARAMS 强>
上面描述的 where 参数可以使用标准的Python数据库 字符串占位符 - &#39;%s&#39; 表示数据库引擎的参数 应自动报价。 params 参数是任何额外的列表 要替换的参数。
示例:
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
始终使用参数,而不是将值直接嵌入其中,因为 参数将确保根据您的报价正确引用值 特别是后端。例如,报价将被正确转义。
答案 1 :(得分:1)
是的,但仅*使用where
的{{1}}参数:https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra
这样的事情应该做:
extra
*如果您创建自定义数据库类型,您应该能够定义自定义运算符,因此...可能能够解决它。我会稍微google一下:)