如何将特定的 SQL 语句实现为 SQLAlchemy ORM 查询

Posted

技术标签:

【中文标题】如何将特定的 SQL 语句实现为 SQLAlchemy ORM 查询【英文标题】:How to implement a specific SQL statement as a SQLAlchemy ORM query 【发布时间】:2021-01-08 15:04:00 【问题描述】:

我正在按照教程制作我的第一个 Flask API (https://medium.com/@dushan14/create-a-web-application-with-python-flask-postgresql-and-deploy-on-heroku-243d548335cc),但现在我想使用 SQLAlchemy 和 PostgreSQL 进行更自定义的查询。我的问题是我怎么能做这样的事情:

query = text("""SELECT enc.*, persona."Persona_Nombre", persona."Persona_Apellido", metodo."MetEnt_Nombre", metodo_e."MetPag_Descripcion" 
FROM "Ventas"."Enc_Ventas" AS enc 
INNER JOIN "General"."Persona" AS persona ON enc."PersonaId" = persona."PersonaId" 
INNER JOIN "Ventas"."Metodo_Entrega" AS metodo ON enc."MetodoEntregaId" = metodo."MetodoEntregaId"
INNER JOIN "General"."Metodo_Pago" AS metodo_e ON enc."MetodoPagoId" = metodo_e."MetodoPagoId" 
INNER JOIN "General"."Estatus" AS estado ON enc. """)

但使用 SQLAlchemy 是为了使用我之前创建的模型。提前感谢您的任何回答!

编辑:

我希望在最终结果中看到的列是:enc.*, persona."Persona_Nombre", persona."Persona_Apellido", metodo."MetEnt_Nombre", metodo_e."MetPag_Descriptcion"

我真的希望我可以分享更多信息,但遗憾的是我现在不能。

【问题讨论】:

【参考方案1】:

从 ORM 层执行此操作,您将引用模型名称(我与您上面查询的名称相匹配,但我确信某些模型/表名称已关闭 - 现在略有调整)。

现在修改为包含您只想查看的特定列(注意我忽略了您的 SQL 别名,ORM 层处理实际的查询构造):

selection = session.query(Enc_Ventas, Persona.Persona_Nombre, Persona.Persona_Apellido, Metodo_Entrega.MetEnt_Nombre, Metodo_Pago.MetPag_Descriptcion)。\

加入(角色,Enc_Ventas.PersonaId == Persona.PersonaId)。 加入(Metodo_Entrega,Enc_Ventas.MetodoEntregaId == Metodo_Entrega.MetodoEntregaId)。\

加入(Metodo_Pago,Enc_Ventas.MetodoPagoId == Metodo_Pago.MetodoPagoId)。\

加入(状态).all()

引用选择集合将通过遍历元组行来实现。一个更健壮和稳定的解决方案是将每个输出行转换为一个字典。

否则,通过包含整个模型,可以通过在 query() 中将模型名称引用为点表示法来单独访问返回的行集合。 如果您需要进一步访问相关表中的列,请使用 .options(joinedload(myTable)) 的 ORM 技术,该技术将在单个数据库查询中引入这些附加列,使用关系名称,也作为点表示法。

您还需要在模型中定义 sqlalchemy relationships 以使其正常工作,并定义底层 SQL 外键。

需要更多细节和/或更具体的问题来进一步帮助,imo。

【讨论】:

我看到了一个类似于你的解决方案,但我不想合并我要加入的每个表的所有列,这正是我来这里询问的原因,因为我觉得这很奇怪。我来自 C# 和实体框架,在那里你可以加入表格,指定你想要添加到最终答案的列,这就是我想知道的,如果可以使用 SQLAlchemy 做同样的事情? 您绝对可以在最终输出中指定您希望看到的列,这样生成的扩展 SQL 语句不会太大或包含多余的列。您可以通过点符号而不是 query() 中的完整模型名称来指定这些列。然后,您可以通过结果元组中的索引访问这些列。提供更详细的需求,包括模型片段,并且可以显示。尽管您有疑虑,但 SQLAlchemy 在其 ORM 接口 (imo) 中非常灵活。 顺便说一句,如果允许 SQLA 从定义的模型外键推断(必须明确),则不需要精心设计的 join() 语句,即 SQLA 查询可能更简洁。 看我添加了我希望在问题中看到的列。 我的答案已更新为这些列。如果答案满足您的原始问题,请勾选接受。

以上是关于如何将特定的 SQL 语句实现为 SQLAlchemy ORM 查询的主要内容,如果未能解决你的问题,请参考以下文章

将同一变量传递到 SQL 语句的多个部分时出错

MySQL 工作台:如何将特定列导出为更新语句?

在SQL语句里面如何将字符型转换成数字型?

如何实现从数据库中取出所有日期,使用SQL语句能够区分出每年的日期。

如何使用 SQL 中的 Case 语句将数据插入临时表

java中PreparedStatement执行带参数的sql语句如何实现模糊查询?