如何在 SQLAlchemy 中将"ANY"筛选器与"<<="运算符结合使用?



我有一个带有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)])

最新更新