SQLAlchemy:如何过滤PgArray列类型?

Vit*_*mar 6 python sql postgresql sqlalchemy

在纯粹的postgres我们可以写:

SELECT * FROM my_table WHERE 10000 = ANY (array_field);
Run Code Online (Sandbox Code Playgroud)

要么

SELECT * FROM my_table WHERE 10000 = ALL (array_field);
Run Code Online (Sandbox Code Playgroud)

如何在没有原始sql的sqlalchemy的帮助下做同样的事情?

Erw*_*ter 21

a = ANY(b_array)相当于1.aIN(elements_of_b_array)

因此您可以使用该in_()方法.

我不记得曾经a = ALL(b_array)在PostgreSQL 中使用过多年.你呢?


如果您正在处理数组列并想要测试它是否包含该中的给定元素(或给定数组的所有元素),那么您可以使用PostgreSQL数组运算符 @>(contains)或更合适的逆兄弟<@(is contained by).

数组运算符具有以下优点:可以使用数组列上的GIN索引支持它们(与ANY构造不同).

你的SQL语句:

SELECT * FROM my_table WHERE 10000 = ANY (array_field);
Run Code Online (Sandbox Code Playgroud)

是(差不多)1相当于

SELECT * FROM my_table WHERE 10000 <@ array_field;
Run Code Online (Sandbox Code Playgroud)

我不是SQLAlchemy的专家,但根据SQLAlchemy手册中教程,您可以使用任何运算符:

如果您遇到过一个真的不可用的运营商,您可以随时使用该op()方法; 这会生成您需要的任何运算符:

>>> print users.c.name.op('tiddlywinks')('foo') users.name tiddlywinks :name_1
Run Code Online (Sandbox Code Playgroud)

大胆强调我的.您的语句在SQLA中可能如下所示:

s = select([my_table], array_field.op('@>')('ARRAY[10000]'))
Run Code Online (Sandbox Code Playgroud)

或者使用PostgreSQL数组值的替代输入语法:

s = select([my_table], array_field.op('@>') (cast('{10000}', int[])))
Run Code Online (Sandbox Code Playgroud)

1 NULL处理有一个细微的区别:

SELECT '{NULL}'::int[] <@ ... -- that's an array with a single NULL element
Run Code Online (Sandbox Code Playgroud)

总是屈服FALSE.

SELECT NULL IN (...)
SELECT NULL = ANY (...)
SELECT NULL::int[] <@ ...
Run Code Online (Sandbox Code Playgroud)

永远屈服NULL.

如果您不打算查询NULL值,可以忽略它.