Reputation: 3579
I'm migrating some code from SqlAlchemy 1.3 to SqlAlchemy 1.4 with Postgres 12. I found a query that looks like this:
session.query(Horse)
.filter(Horse.nicknames.any("charlie", operator=ColumnOperators.ilike))
The type of the column nicknames
is Column(ARRAY(String(64)))
.
It seems to me that what this is doing is queryng any Horse
whose one of their nicknames
is charlie
in a case-insensitive (ilike
) way.
This code seems to work fine in SqlAlchemy==1.3.0
and fails in version 1.4.40
with the following error:
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)
What would be an equivalent way of doing this that works, ideally for both versions?
Upvotes: 3
Views: 611
Reputation: 55600
This query seems to have broken in SQLAlchemy version 1.3.20*. In 1.3.0 it generated this SQL (aliases removed for clarity):
SELECT id, nicknames
FROM horse
WHERE 'charlie' ILIKE ANY (nicknames)
The docs for any mention that it has been superseded by any_, though it doesn't seem to have been formally deprecated. With this knowledge we can build an alternative that generates the same SQL:
import sqlalchemy as sa
...
session.query(Horse).filter(
sa.literal('able').ilike(sa.any_(Horse.nicknames))
)
or in 2.0-style:
sa.select(Horse).where(
sa.literal('charlie').ilike(sa.any_(Horse.nicknames))
)
* I don't see anything in the release notes regarding this change in behaviour, so it might be a regression, but at this stage it's probably better to go with the any_
construct.
Upvotes: 2