我有一个包含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
构造,所以目前我不得不求助于字符串连接。
答案 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)])