SQLAlchemy更新后发生奇怪错误:'list'对象没有属性'_all_columns'

时间:2014-07-24 09:36:50

标签: python sqlalchemy

这是我的查询的简化版本:

subquery = (select(['latitude'])
            .select_from(func.unnest(func.array_agg(Room.latitude))
                         .alias('latitude')).limit(1).as_scalar())
Room.query.with_entities(Room.building, subquery).group_by(Room.building).all()

执行它时,我在SQLAlchemy内部得到一个错误:

  File ".../sqlalchemy/sql/selectable.py", line 429, in columns
    self._populate_column_collection()
  File ".../sqlalchemy/sql/selectable.py", line 992, in _populate_column_collection
    for col in self.element.columns._all_columns:
AttributeError: 'list' object has no attribute '_all_columns'

在调试器中检查它会向我显示:

>>> self.element
<sqlalchemy.sql.functions.Function at 0x7f72d4fcae50; unnest>
>>> str(self.element)
'unnest(array_agg(rooms.id))'
>>> self.element.columns
[<sqlalchemy.sql.functions.Function at 0x7f72d4fcae50; unnest>]

问题始于SQLAlchemy 0.9.4;在0.9.3中一切正常。

在SQLAlchemy 0.9.3中运行时,执行以下查询(按预期方式):

SELECT rooms.building AS rooms_building,
       (SELECT latitude
        FROM unnest(array_agg(rooms.latitude)) AS latitude
        LIMIT 1) AS anon_1
FROM rooms
GROUP BY rooms.building

我在这里做错了还是SQLAlchemy中的错误?

1 个答案:

答案 0 :(得分:0)

这是SQLAlchemy中的一个错误:https://bitbucket.org/zzzeek/sqlalchemy/issue/3137/decide-what-funcxyz-alias-should-do

  

func.foo().alias()实际上应该等同于func.foo().select().alias(),但是在这种情况下,这将推出您不想要的第二级嵌套。所以要对API进行修正可能需要1.0,除非我现在可以确定func.foo().alias()完全无法使用。

根据SQLAlchemy开发人员的说法,正确的方法是:

subquery = (select(['*']).select_from(
                func.unnest(func.array_agg(Room.latitude)))
            .limit(1)
            .as_scalar())

很可能下一个版本(我假设为0.9.8)将恢复旧的行为:

  

我正在恢复旧的行为,但现在只使用select(['*'])。该列未命名。 PG根据FROM中的别名分配列名的行为有点神奇(例如,如果函数返回多个列,那么它会忽略该名称并使用函数报告的名称?)