简体   繁体   English

SQLAlchemy ORM:选择具有多个 JOIN 和 WHERE 子句的特定列

[英]SQLAlchemy ORM: SELECT specific columns with multiple JOIN and WHERE clause

I'm trying to find a more pythonic way of executing SQL queries using the SQLalchemy ORM.我试图找到一种使用 SQLalchemy ORM 执行 SQL 查询的更 Pythonic 的方式。 Below is a sample SQL statement:下面是一个示例 SQL 语句:

SELECT A.payment_plan_id, A.plan_id, A.amount, C.promo_code, B.sso_guid, B.user_id
FROM payment_plans as A
JOIN users as B ON A.user_id = B.user_id
JOIN invoices as C ON A.invoice_id = C.invoice_id
WHERE A.due_date::date < '01/01/2022'::date
AND (A.status = 'pending' OR A.status = 'failed')

Tried this approach:试过这种方法:

orm_query = session.query(
    select(
        payment_plans.payment_plan_id,
        payment_plans.plan_id,
        payment_plans.amount,
        invoices.promo_code,
        users.sso_guid,
        users.user_id,
   )
   .join(users, payment_plans.user_id == users.user_id)
   .join(invoices, payment_plans.invoice_id == invoices.invoice_id)
   .where(payment_plans.due_date < '01/01/2022')
   .where(payment_plans.status in ["pending", "failed"])
)

and I'm always ending up with this error:我总是以这个错误告终:

sqlalchemy.exc.ArgumentError: Column expression or FROM clause expected, got <sqlalchemy.sql.selectable.Select object at 0x7fe342d7ca60>. To create a FROM clause from a <class 'sqlalchemy.sql.selectable.Select'> object, use the .subquery() method.

I'm not sure what it means and I scoured google looking for answers.我不确定这意味着什么,我搜索谷歌寻找答案。 Any help is appreciated.任何帮助表示赞赏。 Thanks!谢谢!

session.query and select both basically do the same thing, but session.query returns instances of your mapped classes while select returns rows like a traditional DB API. session.query 和 select 基本上都做同样的事情,但是 session.query 返回映射类的实例,而 select 返回像传统 DB API 一样的行。 This means that you have to use session.query like you use select in your example and call .all() to receive a QueryResult your objects.这意味着您必须像在示例中使用 select 一样使用 session.query 并调用 .all() 来接收 QueryResult 您的对象。 Or you use select without the outer session.query and use your engine to execute the query.或者您使用不带外部 session.query 的 select 并使用您的引擎来执行查询。 I assume that you want to use the latter:我假设您想使用后者:

query = select(

    payment_plans.payment_plan_id,
    payment_plans.plan_id,
    payment_plans.amount,
    invoices.promo_code,
    users.sso_guid,
    users.user_id,
)
   .join(users, payment_plans.user_id == users.user_id)
   .join(invoices, payment_plans.invoice_id == invoices.invoice_id)
   .where(payment_plans.due_date < '01/01/2022')
   .where(payment_plans.status in ["pending", "failed"])

result = engine.execute(query)

TIP: Install sqlalchemy-stubs (the official type stubs for sqlalchemy) via pip to get API hints for sqlalchemy in your IDE and a better feeling for what works and what not (works with VSCODE at least; you may have to restart your IDE).提示:通过 pip 安装 sqlalchemy-stubs(sqlalchemy 的官方类型存根),以在 IDE 中获取 sqlalchemy 的 API 提示,更好地了解哪些有效,哪些无效(至少适用于 VSCODE;您可能必须重新启动 IDE) .

I managed to make this work by not using select , and notice the use of in_ for value evaluation with a list.我设法通过不使用select来完成这项工作,并注意使用in_进行带有列表的值评估。

 orm_query = (
    session.query(
        payment_plans.payment_plan_id,
        payment_plans.plan_id,
        payment_plans.amount,
        invoices.promo_code,
        users.sso_guid,
        users.user_id,
   )
   .join(users, payment_plans.user_id == users.user_id)
   .join(invoices, payment_plans.invoice_id == invoices.invoice_id)
   .where(payment_plans.due_date < '01/01/2022')
   .where(payment_plans.status.in_(["pending", "failed"]))
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM