14

有谁知道如何在不遍历结果集的情况下从 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)

输出:

0 rows returned by query...

[u'val']
(1,)
(2,)
4

2 回答 2

30

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 值与那些已经出现在行中的人。这样的行将被匹配但不会被修改。在具有这两种样式的后端(例如 MySQL)上,默认情况下将 rowcount 配置为在所有情况下返回匹配计数。

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

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

  • 使用 RETURNING 的语句可能不会返回正确的行数。
于 2012-10-31T02:53:30.350 回答
3

你可以使用这个:

rowcount = len(results._saved_cursor._result.rows)

然后你的代码将是

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

仅经过测试的“查找”查询

这个对我有用。

于 2017-10-11T17:00:37.997 回答