Sqlalchemy JSON массив, выполнить как запрос внутри массива - PullRequest
0 голосов
/ 02 июля 2019

У меня есть таблица в моей базе данных, которая содержит столбец form с типом данных JSONb, и данные в большинстве случаев выглядят так:

id = 1 
form = [{'label': 'x1', 'value': True},
 {'label': 'x2', 'value': 'v1'},
 {'label': 'x3', 'value': 'c2'}];
id = 2 
form = [{'label': 'x1', 'value': True},
 {'label': 'x2', 'value': 'v21'},
 {'label': 'x3', 'value': 'v22'}];

Я хочу знать, возможно ли выполнить поиск в этой таблице, чтобы найти строки, содержащие текст типа c% в элементах в их поле form? т.е. в приведенном выше случае я хочу получить сущность с id = 1;

Нет необходимости делать это в sqlalchemy, но, если возможно, это предпочтительное решение;

1 Ответ

2 голосов
/ 02 июля 2019

Да, вы можете сделать это, разбив его на части:

select id 
from mytable
join lateral (select jsonb_array_elements(form) as elements) as sub1 on true
join lateral (select key, value from jsonb_each_text(elements)) as sub2 on true
WHERE key = 'value' and value like 'c%';
 id
----
  1

Первое боковое соединение помещает каждый элемент массива в свою собственную строку. Второе боковое соединение помещает каждую пару ключ-значение объекта в свой ряд. Затем мы просто ищем строки, в которых key = 'value' и value как 'c%'. Если вы также хотите найти метки со значением типа «c%», просто удалите часть ключ = «значение».

EDIT: Это будет проще в postgres 12 с json_path:

select id 
from mytable 
where jsonb_path_exists(form, '$.**.value ? (@ starts with "c")');
...