Подзапрос Django со статическим выражением VALUES

Возможно ли с помощью Django ORM написать подзапрос, который выбирает из набора фиксированных значений?

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
  ;

Вывод такого запроса может выглядеть примерно так:

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

Я знаю, что код Django будет выглядеть примерно так:

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

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

Но что входит в ...?

Насколько я знаю, в Django нельзя определить такие "in-memory" таблицы, по крайней мере, сейчас.

Печальная реальность заключается в том, что реализация Django .bulk_update(…) [Django-doc], которая по сути является тем, что вы здесь делаете, имеет ту же самую проблему. Она решает ее немного "неуклюжим" способом: длинной последовательностью CASE … WHEN … THEN … END. Мы можем сделать то же самое с помощью:

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()])
)

Я написал статью об этом [django-antipatterns], но опять же, это не хороший способ сделать это. Возможно, лучшим способом было бы даже определить модель, в которую можно сбрасывать элементы, а затем позволить JOIN сделать всю работу.

Вернуться на верх