用作表达式的子查询返回的多行

时间:2016-02-06 23:21:49

标签: postgresql sqlalchemy

我所有的SQLAlchemy模型都很好地查询,但是有一个给我:

more than one row returned by a subquery used as an expression

这是SQLAlchemy生成的(缩短的)SQL:

SELECT poi.key
,poi.pok
,poi.noc
,coalesce((
    SELECT CASE 
        WHEN (sum(item.noc) IS NULL)
            THEN NULL
        ELSE :param_1
        END AS anon_1
    FROM item,poi
    WHERE poi.key = item.poi_key
    GROUP BY item.key
    ), poi.noc) AS coalesce_1
,coalesce((
    SELECT sum(soi.noc) AS sum_1
    FROM soi
    WHERE soi.poi_key = poi.key
        AND soi.is_shipped = 0
    ), :param_2) AS coalesce_2
,coalesce((
    SELECT CASE 
        WHEN (sum(item.noc) IS NULL)
            THEN NULL
        ELSE :param_1
        END AS anon_1
    FROM item,poi
    WHERE poi.key = item.poi_key
    GROUP BY item.key
    ), poi.noc) - ee((
    SELECT sum(soi.noc) AS sum_1
    FROM soi
    WHERE soi.poi_key = poi.key
        AND soi.is_shipped = 0
    ), :param_2) AS anon_2
FROM poi

模型是:

class POI(Base):
    key = Column(Integer, primary_key=True)
    pok = Column(Integer, nullable=False)
    noc = Column(Integer, nullable=False)
    __table_args__ = (UniqueConstraint(pok,),
        ForeignKeyConstraint([pok],),{})

我正在使用scoped_session,因为我的应用程序是多线程的,我认为这可能是问题所在。但事实并非如此。我尝试过使用Session的每个变体,但问题仍然存在。奇怪的是,在应用程序初始化时,当启动从db获取数据的多个线程时,只有此查询才会抛出错误。仅调用此查询(手动)可以正常工作。所以问题显然是与其他查询的交互。

错误对我来说有点模糊,但我认为问题是子查询应该返回一个结果,而不是很多。我不知道从哪里开始寻找答案。这是一个线程问题吗?会话问题?还有别的吗?

1 个答案:

答案 0 :(得分:0)

我相信您在2个子查询中不需要FROM item,poi,我也会删除group by。返回涉及的案例表达式:param_1我不确定下面我建议的是否正确,但是你需要创建一个SUM()值,然后才能测试该SUM()是否为NULL。

SELECT
      poi.key
    , poi.pok
    , poi.noc
    , COALESCE((
            SELECT SUM(COALESCE(item.noc,:param_1))
            FROM item
            WHERE poi.key = item.poi_key
      )
      , poi.noc) AS coalesce_1
    , COALESCE((
            SELECT
                  SUM(soi.noc) AS sum_1
            FROM soi
            WHERE soi.poi_key = poi.key
                  AND soi.is_shipped = 0
      )
      , @param_2) AS coalesce_2
    , COALESCE((
            SELECT SUM(COALESCE(item.noc,:param_1))
            FROM item
            WHERE poi.key = item.poi_key
      )
      , poi.noc) - ee((
            SELECT
                  SUM(soi.noc) AS sum_1
            FROM soi
            WHERE soi.poi_key = poi.key
                  AND soi.is_shipped = 0
      )
      , :param_2) AS anon_2
FROM poi