Я переношу некоторый код из SqlAlchemy 1.3 в SqlAlchemy 1.4 с Postgres 12. Я нашел запрос, который выглядит так:
session.query(Horse)
.filter(Horse.nicknames.any("charlie", operator=ColumnOperators.ilike))
Тип столбца nicknames
— Column(ARRAY(String(64)))
.
Мне кажется, что это делает запрос любого Horse
, чей один из их nicknames
является charlie
без учета регистра (ilike
).
Этот код работает нормально в SqlAlchemy==1.3.0
и дает сбой в версии 1.4.40
со следующей ошибкой:
sqlalchemy.exc.UnsupportedCompilationError:
Compiler <sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0x7fce54c80f10>
can't render element of type <function ColumnOperators.ilike at 0x7fce92944280>
(Background on this error at: https://sqlalche.me/e/14/l7de)
Каким был бы эквивалентный способ сделать это, который идеально подходит для обеих версий?
Похоже, этот запрос не работает в версии SQLAlchemy 1.3.20*. В 1.3.0 он сгенерировал этот SQL (псевдонимы удалены для ясности):
SELECT id, nicknames
FROM horse
WHERE 'charlie' ILIKE ANY (nicknames)
В документах для any упоминается, что он был заменен any_, хотя, похоже, формально он не объявлен устаревшим. С этими знаниями мы можем создать альтернативу, которая генерирует тот же SQL:
import sqlalchemy as sa
...
session.query(Horse).filter(
sa.literal('able').ilike(sa.any_(Horse.nicknames))
)
или в стиле 2.0:
sa.select(Horse).where(
sa.literal('charlie').ilike(sa.any_(Horse.nicknames))
)
* Я ничего не вижу в примечаниях к выпуску относительно этого изменения в поведении, так что это может быть регрессией, но на данном этапе, вероятно, лучше использовать конструкцию any_
.
@python_user ответы здесь предполагают, что нет, или, по крайней мере, нелегко.
это новое для меня, поэтому +1, тоже не ОП, но я хотел бы знать, можно ли также применить «начинает с» (вместо ilike) таким же образом? например: "любой элемент начинается с Foo"