Боковое соединение в наборе запросов django (для использования функции jsonb_to_recordset postgresql) - PullRequest
1 голос
/ 25 сентября 2019

У меня есть модель "myModel", сохраняющая некоторые данные в (postgresql) jsonField с именем "json". Типичная структура данных json: {key: [{"a": 1, "b": 2}, {"a": 3, "b": 4}]}.

Я бы хотел отфильтровать набор запросов myModel по значениям "a" или "b".Я могу также захотеть агрегировать по «a» или «b»

Так что «unnesting» массив (json -> key) будет очень полезен, но я не могу понять, как это сделать с помощью djangoapi.

Я попытался выполнить "unnesting" прямо в postgresql с помощью следующего SQL-запроса.

SELECT * 
FROM "myModel"
join lateral jsonb_to_recordset("myModel"."json" -> 'key') as r("a" int, "b" int) on true
LIMIT 5

Мы можем даже сделать его более компактным, используя сокращенную запись для бокового соединения

SELECT * 
FROM "myModel", jsonb_to_recordset("myModel"."json" -> 'key') as r("a" int, "b" int)
LIMIT 5

Но я понятия не имею, как сделать что-то эквивалентное с помощью API django.Я пробовал несколько вещей с аннотацией и RawSQL, но ни одна из них, похоже, не действует в предложении «FROM».Именно в это место я должен добавить оператор 'jsonb_to_recordset'.Возможно, я мог бы использовать функцию raw для размещения моего исходного SQL, но это означало бы, что я не могу «фильтровать» или «агрегировать» объединенный набор запросов с помощью API django…. Мне нужно делать все в rawSQL.что не очень удобно для того, что я должен сделать.

Другой подход - использовать функцию «extra» queryset, которая позволяет добавить дополнительную таблицу в предложении sql FROM.К сожалению, если я сделаю:

qs = myModel.objects.all()
qs = qs.extra(tables = ["""jsonb_to_recordset("myApp_myModel"."json" -> 'key') as r("a" int, "b" int)"""])
qs = qs.values()
print(qs.query)

я получу запрос, который django выполнит:

SELECT * 
FROM "myModel", "jsonb_to_recordset("myModel"."json" -> 'key') as r("a" int, "b" int)"

Это довольно близко к тому, что мне нужно ... за исключением того, что django добавил дополнительные кавычки вокругдополнительное имя «таблицы», которое я предоставил ... Так что функция больше не работает.

Есть идеи, как с этим справиться?

Заранее спасибо, Loic

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...