SQLAlchemy: как фильтровать по типам столбцов PgArray?
На чистом postgres мы можем написать:
SELECT * FROM my_table WHERE 10000 = ANY (array_field);
или же
SELECT * FROM my_table WHERE 10000 = ALL (array_field);
Как сделать то же самое с помощью sqlalchemy без raw sql?
1 ответ
a = ANY(b_array)
эквивалентно a
IN
(elements_of_b_array)
1
Поэтому вы можете использовать in_()
метод.
Я не помню, чтобы когда-либо использовал a = ALL(b_array)
за все мои годы с PostgreSQL. А у тебя
Если вы имеете дело со столбцом массива и хотите проверить, содержит ли он данный элемент (или все элементы данного массива) в этом столбце, то вы можете использовать операторы массива PostgreSQL. @>
(contains
) или точнее обратный брат <@
(is contained by
).
Преимущество операторов массива заключается в том, что они могут поддерживаться индексом GIN для столбца массива (в отличие от ANY
построить).
Ваш оператор SQL:
SELECT * FROM my_table WHERE 10000 = ANY (array_field);
является (почти) 1 эквивалентом
SELECT * FROM my_table WHERE 10000 <@ array_field;
Я не специалист по SQLAlchemy, но в соответствии с руководством в руководстве по SQLAlchemy, вы можете использовать любой оператор:
Если вы столкнулись с оператором, который действительно не доступен, вы всегда можете использовать
op()
Способ; это генерирует любой оператор, который вам нужен:>>> print users.c.name.op('tiddlywinks')('foo') users.name tiddlywinks :name_1
Жирный акцент мой. Ваше утверждение может выглядеть следующим образом в SQLA:
s = select([my_table], array_field.op('@>')('ARRAY[10000]'))
Или с альтернативным синтаксисом ввода для значений массива PostgreSQL:
s = select([my_table], array_field.op('@>') (cast('{10000}', int[])))
1 Есть небольшая разница с обработкой NULL:
SELECT '{NULL}'::int[] <@ ... -- that's an array with a single NULL element
всегда дает FALSE
,
SELECT NULL IN (...)
SELECT NULL = ANY (...)
SELECT NULL::int[] <@ ...
всегда уступать NULL
,
Если вы не собираетесь запрашивать NULL
значения, вы можете игнорировать это.