SqlAlchemy: Query JSONB столбец, содержащий список словарей, чтобы получить список общего ключа для сравнения с предопределенным списком - PullRequest
0 голосов
/ 23 октября 2019

У меня есть столбец JSONB, который выглядит следующим образом: url_map:

[
    {"id": "id_1", "url": "url_1"},
    {"id": "id_2", "url": "url_2"},
    {"id": "id_3", "url": "url_3"},
    {"id": "id_4", "url": "url_4"},
]

Обратите внимание, что это столбец JSONB, представляющий собой список словарей.

Когда я пытаюсьвведите новую запись в эти данные, у меня есть набор идентификаторов, которые приходят в виде списка:

['id_1', 'id_2', 'id_3', 'id_4']

Мне нужно выполнить запрос сеанса ORM для этой таблицы, которая скажет мне, если есть какие-либо записиу которых есть столбцы url_map, содержащие словари, в которых есть все идентификаторы во входящем списке.

Я нашел достаточно простой прямой запрос SQL, который может сделать это для меня:

select id
from mapper
where ARRAY(SELECT json_array_elements(url_mp::json)->>'id')
    = ARRAY['id_1', 'id_2', 'id_4', 'id_4'];

Это будет либо возвращать строку, если она существует, либо ничего, если нет.

Мой кошмар заключался в том, чтобы преобразовать это в код ORM.

Вот что я до сих пор придумывал, используя ORM:

new_ids = ['id_1', 'id_2', 'id_4', 'id_4']
with session_() as session:
    sub_query = session.query(
        func.json_array_elements(mapper.url_map.op('->>')('id')).label('id')
    ).subquery()

    result = session.query(mapper.id).filter(
        sub_query.c.csku == new_ids
    ).all()

Я ожидал этогочтобы вернуть идентификатор строки, но result возвращает пустой список. НУЖНО, в базе данных есть действительные записи.

Необработанный запрос, который я мог получить с помощью

str(query.statement.compile(dialect=postgresql.dialect()))

, просто говорит

'SELECT mapper.id \nFROM mapper \nWHERE false'

Я пытался выполнить типизацию с ARRAY, но безуспешно. Любая помощь по этому вопросу будет принята с благодарностью!

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