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 に関する注意:

  • この属性は、一致した行数を返しますが、これは実際に変更された行数と必ずしも同じではありません。たとえば、UPDATE ステートメントは、指定された SET 値がすでに列に並んでいる人。このような行は一致しますが、変更されません。MySQL など、両方のスタイルを特徴とするバックエンドでは、rowcount はデフォルトで、すべての場合に一致数を返すように構成されています。

  • ResultProxy.rowcount は、UPDATE または DELETE ステートメントと組み合わせた場合にのみ役立ちます。行がバッファリングされていない場合、DBAPI はこの機能をサポートできないため、Python DBAPI が言うこととは反対に、SELECT ステートメントの結果から利用可能な行数を返しません。

  • ResultProxy.rowcount は、すべての方言で完全に実装されているわけではありません。特に、ほとんどの DBAPI は、executemany 呼び出しからの集計行数の結果をサポートしていません。ResultProxy.supports_sane_rowcount() および ResultProxy.supports_sane_multi_rowcount() メソッドは、各使用法がサポートされていることがわかっている場合、方言から報告します。

  • RETURNING を使用するステートメントは、正しい行数を返さない場合があります。
于 2012-10-31T02:53:30.350 に答える