python - 使用 sqlalchemy 嵌套 SELECT

标签 python sqlalchemy

我想使用 sqlalchemy 创建一个带有嵌套 SELECT 的查询,但我无法得到预期的结果。

我当然简化了以下查询,因此这篇文章很容易理解。

这是我想构建的查询:

SELECT pear_table.size,
       (SELECT MIN(apple.apple_date)
        FROM apple
        WHERE apple_id = pear_table.pear_id ) apple_min,
       (SELECT max(lemon.lemon_date)
        FROM lemon
        WHERE lemon_id = pear_table.pear_id ) lemon_max
FROM
  (SELECT pear_id
   FROM pear
   WHERE pear_color = 'green') pear_table

请注意,我在两个子查询中都使用了“pear_id”。当用作字符串时,此查询运行良好。

现在我尝试使用 sqlalchemy 构建它:
APPLE = wrapper.getMapper('apple')
LEMON = wrapper.getMapper('lemon')
PEAR = wrapper.getMapper('pear')

pear_table = select([PEAR.apple_id])
pear_table.append_whereclause(PEAR.pear_color == 'green')

apple_min = select([func.min(APPLE.apple_date).label('apple_min')])
apple_min.append_whereclause(APPLE.apple_id == pear_table.pear_id)

lemon_max = select([func.min(LEMON.apple_date).label('lemon_max')])
lemon_max.append_whereclause(LEMON.lemon_id == pear_table.pear_id)

main_query = select([pear_table.c.pear_id,
                     apple_min.c.apple_min,
                     lemon_max.c.lemon_max])

这是 sqlalchemy 使用此代码构建的内容:
SELECT pear_table.size,
       apple_min,
       lemon_max
FROM
  (SELECT pear_id
   FROM pear
   WHERE pear_color = 'green') pear_table,
  (SELECT MIN(apple.apple_date)
   FROM apple
   WHERE apple_id = pear_table.pear_id ) apple_min,
  (SELECT max(lemon.lemon_date)
   FROM lemon
   WHERE lemon_id = pear_table.pear_id ) lemon_max

问题是我的 2 个子查询 'apple' 和 'lemon' 无法访问 'pear_id',因为 sqlalchemy 将子查询放在 'FROM' 子句中。

我尝试使用相关选项解决我的问题:
.
apple_min = select([func.min(APPLE.apple_date).label('apple_min')]).correlate(None)
.
lemon_max = select([func.min(LEMON.apple_date).label('lemon_max')]).correlate(None)
.

这是我得到的:
SELECT pear_table.size,
       apple_min,
       lemon_max
FROM
  (SELECT pear_id
   FROM pear
   WHERE pear_color = 'green') pear_table,
  (SELECT MIN(apple.apple_date)
   FROM apple,
        (SELECT pear_id
         FROM pear
         WHERE pear_color = 'green')
   WHERE apple_id = pear_table.pear_id ) apple_min,
  (SELECT max(lemon.lemon_date)
   FROM lemon,
        (SELECT pear_id
         FROM pear
         WHERE pear_color = 'green')
   WHERE lemon_id = pear_table.pear_id ) lemon_max

这会复制“FROM pear_id ...”,出于明显的性能原因,我不希望重复查询。
  • 难道我做错了什么?
  • 有没有更好的方法来构建我的查询?
  • sqlalchemy 允许我按照我想要的方式构建吗?
  • 有没有办法将子查询直接放在主“SELECT”子句中?

  • 我目前使用的是 sqlalchemy 0.4,但我用 0.8 尝试了同样的事情,结果是一样的。

    最佳答案

    试试这个(关键是使用 Scalar Selects ):

    pear_table = (
        select([PEAR.pear_id])
        .where(PEAR.pear_color == 'green')
    )
    
    apple_min = (
        select([func.min(APPLE.apple_date).label('apple_min')])
        .where(APPLE.apple_id == pear_table.c.pear_id)
    ).as_scalar()
    
    lemon_max = (
        select([func.min(LEMON.lemon_date).label('lemon_max')])
        .where(LEMON.lemon_id == pear_table.c.pear_id)
    ).as_scalar()
    
    main_query = select([pear_table.c.pear_id, apple_min, lemon_max])
    print(main_query)
    

    关于python - 使用 sqlalchemy 嵌套 SELECT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28090140/

    相关文章:

    python - 如何从具有关系的表中检索数据 - 多对多 (SQLAlchemy)?

    python - 如何在 Python 中将不同轴的绘图标签添加到同一图例中?

    python - SQLite 中的文件锁

    python - 基于另一个属性的列默认值

    python - 如何为 SQLAlchemy 中的关系设置默认值?

    python - 使用 SQLAlchemy 获取最后插入的 ID

    python - 使用 matplotlib 的年度数据极坐标图

    python - 有效地将值分配给groupby中的第一行

    python - 多次将相同的值 append 到列表

    Python - Firebase 数据库引用错误