Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django subquery with static VALUES expression

Is it possible using the Django ORM to write a subquery which SELECTs from a set of fixed values?

SELECT
  id,
  name,
  (
    SELECT
    new_ages.age
    FROM
    (VALUES ('homer', 35), ('marge', 34)) AS new_ages(name, age)
    WHERE new_ages.name = ages.name
  ) AS new_age
FROM
  ages
  ;

The output from such a query might be something like:

person_id  name    age
        1  homer   35
       42  marge   34
       99  bart    null

I know that the Django code would look something like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

from django.db.models import OuterRef, Subquery
from my_app.models import Person

Person.objects.annotate(age=Subquery(...(name=OuterRef("name")))

But what goes in the ...?

>Solution :

As far as I know, you can’t define such "in-memory" tables in Django, or at least not right now.

The sad reality is that Django’s .bulk_update(…) implementation [Django-doc], which essentially is what you are doing here, has the same problem. It solves that in a bit of a "clumsy" way: a long CASE … WHEN … THEN … END sequence. We can do this the same way with:

from django.db.models import Case, Value, When

new_ages = {'homer': 35, 'marge': 34}

Person.objects.annotate(
    age=Case(*[When(name=k, then=Value(v)) for k, v in new_ages.items()])
)

I wrote an article about this [django-antipatterns], but again, it is not a good way to do this. Perhaps the best way would even be to define a model where one can dump items into, and then let the JOIN do the work.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading