Подзапрос 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 сделать всю работу.