Вы просто забыли, что ваш JSON-путь должен включать и самый внешний массив:
User.query.filter(User.contact_list.contains([{"phone": ["147889"]}])).all()
вернет искомого пользователя. Исходный запрос соответствовал бы, если бы ваш JSON содержал объект с ключом «телефон» и т. Д. Обратите внимание, что это возвращает рассматриваемый объект User
, а не конкретный объект / имя из структуры JSON. Если вы хотите, чтобы это, как кажется, являлось конечной целью, вы могли бы расширить элементы массива каждого пользователя, отфильтровать их по полученным записям и выбрать имя:
val = db.column('value', type_=JSONB)
db.session.query(val['name'].astext).\
select_from(User,
db.func.jsonb_array_elements(User.contact_list).alias()).\
filter(val.contains({"phone": ["147889"]})).\
all()
С другой стороны, приведенный выше запрос не так удобен для индексов, как первый, поскольку он должен расширять все массивы перед фильтрацией, поэтому может быть полезно сначала найти пользователей, которые содержат телефон в своем контакте список в подзапросе или CTE, а затем разверните и отфильтруйте.