我如何使用" ANY"使用"<< ="进行过滤SQLAlchemy中的运算符?

时间:2017-12-13 14:46:55

标签: python postgresql sqlalchemy

我有一个包含INET列的表,并希望运行一个查询,过滤所有给定网络中的任何条目。例如:

CREATE TABLE foo (
   cidr INET
);

在SQL中我可以编写以下内容:

SELECT cidr FROM foo WHERE cidr <<= ANY '{"192.168.1.0/24", "192.168.3.0/24"}';

我发现the "any" operator in SQLAlchemy适用于标准运算符,但无法使其与<<=运算符一起使用。我该怎么做?

所以我有这样的事情:

from sqlalchemy.dialects.postgresql import Any

query = session.query(Foo)
query = query.filter(Any(
    Foo.cidr,
    [ip_network('192.168.1.0/24'), ip_network('192.168.3.0/24')],
    operator=?  # <-- What do I need to put here?
))

此外,该模型定义了一个自定义类型以适应&#34; ip_network&#34;键入适当的DB类型。这个更改阻止我使用绑定参数的text构造,所以目前我不得不求助于字符串连接。

1 个答案:

答案 0 :(得分:2)

要解决您的紧急问题,您可以使用custom_op

session.query(Foo).filter(Any(
    Foo.cidr,
    array([cast('192.168.1.0/24', INET), cast('192.168.3.0/24', INET)]),
    operator=custom_op("<<="),
))

dialects.postgresql.Any已被弃用,而sql.expression.any_更为自然,使用起来更为自然:

arr = array([cast('192.168.1.0/24', INET), cast('192.168.3.0/24', INET)])
session.query(Foo).filter(Foo.cidr.op("<<=")(any_(arr)))

这会像这样呈现SQL:

SELECT ...
FROM foo 
WHERE foo.cidr <<= ANY (ARRAY[CAST(%(param_1)s AS INET), CAST(%(param_2)s AS INET)])