I have a simple model with 2 fields:
class Simple(Model)
class Meta:
index_together = True
a = IntField()
b = IntField()
I would like to generate an SQL query for tuples of values for a,b
.
e.g.
select *
from SimpleModel
where (a,b) in ((1,1), (4,8), ...)
I know how to create something like:
select *
from SimpleModel
where ((a = 1 and b = 1) or (a = 4 and b = 8))
Which is logically the same, but I think my DB has a problem when the number of possible values is very big (I am using Postgresql), also the query itself is much longer so it's heavier on the network, and probably harder for it to analyze and read it correctly (i.e. use the composite index in this case).
So, the question is, can I get Django to create the query in the first form?
Thanks!
@Wolph answer is correct but I would do it this way
tuple_of_tuples = ((1,1), (4,8))
Simple.objects.extra(where=['(a,b) in %s'], params=[tuple_of_tuples])
Check here about passing a tuple and not a list
Passing lists or tuples as arguments in django raw sql
For the params
I quote from Django docs
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra
params
The where parameter described above may use standard Python database string placeholders — '%s' to indicate parameters the database engine should automatically quote. The params argument is a list of any extra parameters to be substituted.
Example:
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
Always use params instead of embedding values directly into where because params will ensure values are quoted correctly according to your particular backend. For example, quotes will be escaped correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With