我有一个带有INET列的表,并想运行一个查询过滤所有在任何一组给定网络中的条目。例如:
CREATE TABLE foo (
cidr INET
);
在sql中,我可以写下以下内容:
SELECT cidr FROM foo WHERE cidr <<= ANY '{"192.168.1.0/24", "192.168.3.0/24"}';
我在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?
))
此外,该模型定义了一种自定义类型,以使" ip_network"类型适用于适当的DB类型。此更改使我无法使用带有绑定参数的text
构造,因此我当前必须求助于字符串串联。
解决您的直接问题,您可以使用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)])