SQL Alchemy ResultProxy.rowcount不应为零

tpo*_*eux 10 python sqlalchemy rowcount

有没有人知道如何从SQL Alchemy查询ResultProxy对象获取行计数而不循环结果集?ResultProxy.rowcount属性显示0,我希望它的值为2.对于更新,它显示受影响的行数,这是我所期望的.

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine(
    'oracle+cx_oracle://user:pass@host:port/database'
    )

session = sessionmaker(
    bind = engine
    , autocommit = False
    , autoflush = False
    )()

sql_text = u"""
    SELECT 1 AS Val FROM dual UNION ALL
    SELECT 2 AS Val FROM dual
    """

results = session.execute(sql_text)

print '%s rows returned by query...\n' % results.rowcount
print results.keys()

for i in results:
    print repr(i)
Run Code Online (Sandbox Code Playgroud)

输出:

0 rows returned by query...

[u'val']
(1,)
(2,)
Run Code Online (Sandbox Code Playgroud)

zzz*_*eek 22

resultproxy.rowcount最终是DBAPI属性cursor.rowcount的代理.大多数DBAPI不通过此属性为SELECT查询提供"行数"; 其主要目的是提供UPDATE或DELETE语句匹配的行数.实际上,关系数据库不知道特定语句将返回多少行,直到找到所有这些行为止; 许多DBAPI实现将在数据库找到它们时开始返回行,而不进行缓冲,因此在这些情况下甚至没有这样的计数.

要获得SELECT查询将返回的行数,您需要预先执行SELECT COUNT(*),或者需要将所有行提取到数组中并对数组执行len().

ResultProxy.rowcount的注释进一步讨论了这个问题(http://docs.sqlalchemy.org/en/latest/core/connections.html?highlight=rowcount#sqlalchemy.engine.ResultProxy.rowcount):

有关ResultProxy.rowcount的注释:

  • 此属性返回匹配的行数,这不一定与实际修改的行数相同 - 例如,如果给定的SET值与给定的行相同,则UPDATE语句可能在给定行上没有净更改那些已经存在的人.这样的行将匹配但不会被修改.在具有两种样式(例如MySQL)的后端上,默认情况下配置rowcount以在所有情况下返回匹配计数.

  • ResultProxy.rowcount 与UPDATE或DELETE语句一起使用.与Python DBAPI所说的相反,它不会返回SELECT语句结果中可用的行数,因为DBAPI在行无缓冲时不能支持此功能.

  • 所有方言都可能无法完全实现ResultProxy.rowcount.特别是,大多数DBAPI不支持executemany调用的聚合行数结果.如果已知每个用法都受支持,则ResultProxy.supports_sane_rowcount()和ResultProxy.supports_sane_multi_rowcount()方法将从方言报告.

  • 使用RETURNING的语句可能无法返回正确的行数.