【问题标题】:Convert raw SQL to SQLAlchemy query将原始 SQL 转换为 SQLAlchemy 查询
【发布时间】:2015-01-31 08:43:19
【问题描述】:
SELECT * 
FROM product_stocks 
WHERE detected_date = (
                         SELECT MAX(detected_date) 
                         FROM product_stocks 
                         WHERE id = 18865
                      ) 
      AND id = 18865;

将其转换为 SQLAlchemy 查询字符串时遇到很多麻烦。最有效的方法是什么?

【问题讨论】:

  • “最有效的方式”是什么意思?您是否在甚至不知道如何构建查询之前就尝试优化它?
  • 另外,您使用的是 SQLAlchemy ORM,还是只使用查询表达式语言?

标签: python sql database postgresql sqlalchemy


【解决方案1】:

您可以使用from_statement 执行原始 SQL 查询并在 SQL-Alchemy 对象中获取它。当编写普通 SQL 比编写 SQLAlchemy 语法更容易时,这会有所帮助。

Session.query(YourClass).from_statement(text('''SELECT * FROM product_stocks 
WHERE detected_date = (SELECT MAX(detected_date) FROM product_stocks WHERE id = 18865)
AND id = 18865;''')).all()

【讨论】:

  • 你知道如何从经典的 SQLAlchemy 中做到这一点吗?
  • 很久没用SQLAlchemy了。但据我所知,这是做到这一点的方法。不确定您对经典 SQL 炼金术的含义。但也许你的意思是特定模型的短句柄,它只替换了Session.query(class)。休息应该是一样的。它只是关于您要绑定数据的对象。但我可能是错的,因为正如我所说,我很长时间没有使用它。
  • 如果有人遇到这个问题,我发现以下答案很有用stackoverflow.com/questions/23344728/…
【解决方案2】:

下面将重新创建您要求的 SQL:

_id = 18865
T = aliased(ProductStock, name="T")
T1 = aliased(ProductStock, name="T1")
subquery = (
    session.query(func.max(T1.detected_date).label("detected_date"))
    .filter(T1.id == _id)
    # .filter(T1.id == T.id)  # @note: i prefer this one to the line above
    .as_scalar()
)
qry = (
    session.query(T)
    .filter(T.detected_date == subquery)
    .filter(T.id == _id)
)

这是实现您想要的最有效的方法吗? - 我不太确定,但没有足够的信息

【讨论】:

    【解决方案3】:

    使用经典的 SQLAlchemy:

    sql = '从栏选择 foo' sql = 文本(sql) sql = sql.columns() # 这让它用作子查询 sel = select(['foo']).select_from(sql) # 对于复杂的查询,我需要这个,否则列会不明确 sel = sel.alias('sel') 加入 = sel.outerjoin(baz_t, baz_t.foo==sel.foo) final = select([sel.c.foo]).select_from(joined)

    请注意,columns() 是必需的,如果查询很复杂,alias() 会很有帮助。

    以下text 文档很有帮助。

    【讨论】:

      猜你喜欢
      • 2017-04-25
      • 2019-02-03
      • 2019-06-11
      • 2019-03-20
      • 1970-01-01
      • 2019-05-31
      • 2022-08-18
      • 1970-01-01
      • 2017-01-05
      相关资源
      最近更新 更多