In pure postgres we can write:
SELECT * FROM my_table WHERE 10000 = ANY (array_field);
or
SELECT * FROM my_table WHERE 10000 = ALL (array_field);
How to do the same with the help of sqlalchemy without raw sql?
a = ANY(b_array) is equivalent to aIN(elements_of_b_array)1.
Therefore you can use the in_() method.
I can't remember ever having used a = ALL(b_array) in all my years with PostgreSQL. Have you?
If you are dealing with an array column and want to test whether it contains a given element (or all elements of a given array) in that column, then you can utilize PostgreSQL array operators @> (contains) or more appropriately the inverse sibling <@ (is contained by).
Array operators carry the advantage that they can be supported with a GIN index on the array column (unlike the ANY construct).
Your SQL statement:
SELECT * FROM my_table WHERE 10000 = ANY (array_field);
is (almost)1 equivalent to
SELECT * FROM my_table WHERE 10000 <@ array_field;
I am no expert with SQLAlchemy, but according to the tutorial in the SQLAlchemy manual, you can use any operator:
If you have come across an operator which really isn’t available, you can always use the
op()method; this generates whatever operator you need:>>> print users.c.name.op('tiddlywinks')('foo') users.name tiddlywinks :name_1
Bold emphasis mine. Your statement could look like this in SQLA:
s = select([my_table], array_field.op('@>')('ARRAY[10000]'))
Or with alternative input syntax for PostgreSQL array values:
s = select([my_table], array_field.op('@>') (cast('{10000}', int[])))
1 There is a subtle difference with NULL handling:
SELECT '{NULL}'::int[] <@ ... -- that's an array with a single NULL element
always yields FALSE.
SELECT NULL IN (...)
SELECT NULL = ANY (...)
SELECT NULL::int[] <@ ...
always yield NULL.
If you are not going to query for NULL values, you can ignore this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With