如何使用SQLAlchemy的ORM筛选多个字段?SQLAlchemy中的复合字段筛选
实施例:
SELECT p.* FROM product p
WHERE (p.barcode, p.partner) NOT IN (
SELECT barcode, partner
FROM unallowed_products
);
如何使用SQLAlchemy的ORM筛选多个字段?SQLAlchemy中的复合字段筛选
实施例:
SELECT p.* FROM product p
WHERE (p.barcode, p.partner) NOT IN (
SELECT barcode, partner
FROM unallowed_products
);
让我们为了寻找可能的解决办法之前,以减少冗长定义一些别名:
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。 这基本上是你自己的解决方案。 同样,没有理由使用它,因为其他版本更清洁,不需要转换为字符串等。
该查询应解决的问题:
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))
这棘手溶液应为工作几乎每一种情况。