如何使用SQLAlchemy的ORM按多个字段进行过滤?
示例:
SELECT p.* FROM product p
WHERE (p.barcode, p.partner) NOT IN (
SELECT barcode, partner
FROM unallowed_products
);
答案 0 :(得分:1)
在查看可能的解决方案之前,让我们定义一些别名以减少冗长:
P, U = Product, UnallowedProduct
这是非常通用的解决方案,应该适用于所有后端(RDBMS)
q = (
session.query(P)
.outerjoin(U, and_(P.barcode == U.barcode, P.partner == U.partner))
.filter(U.id == None)
)
这不适用于所有后端,但应该适用于mySQL,postgresql
见tuple_
documentation
q = (
session.query(P)
.filter(~tuple_(P.barcode, P.partner).in_(
select([U.barcode, U.partner])
))
)
见this answer。 没有理由使用它作为版本1和版本-2更清洁。
见this question。 这基本上是你自己的解决方案。 同样,没有理由使用它,因为其他版本更清晰,并且不需要转换为字符串等。
答案 1 :(得分:0)
此查询应该可以解决问题:
SELECT p.* FROM product p
WHERE (p.barcode || "_" || p.partner) NOT IN (
SELECT barcode || "_" || partner
FROM unallowed_products
);
可以像这样翻译成SQLAlchemy ORM:
subquery = session.query(
cast(UnallowedProducts.barcode, type_=Text) +
'_' +
cast(UnallowedProducts.partner, type_=Text)
).subquery()
session.query(Product)\
.filter((
cast(Product.id, type_=Text) +
'_' +
cast(Product.partner, type_=Text)
).notin_(subquery))
这个棘手的解决方案几乎适用于所有情况。