5

私はTrac-Pluginに取り組んでいます...

データを取得するために、カーソル オブジェクトを作成し、次のような結果テーブルを取得します。

 db = self.env.get_db_cnx()
 cursor = db.cursor()
 cursor.execute("SELECT...") 

現在、結果は 3 つの異なる関数で使用されています。私の問題は、最初のループ中にカーソルが消去されていることです(ここで言われているようにhttp://packages.python.org/psycopg2/cursor.html )

次に、カーソル オブジェクトをコピーしようとしましたが、これも失敗しました。copy(cursor)関数は大きなデータセットに問題があるようで、とにかく関数はdeepcopy(cursor)失敗します (このバグhttp://bugs.python.org/issue1515によると)。

この問題を解決するにはどうすればよいですか?

4

2 に答える 2

15

有限反復可能からの値の保存は簡単です。

results = list(cursor)

iterableを繰り返し処理し、結果をリストに保存します。このリストは、必要に応じて何度でも繰り返すことができます。

カーソルのコピーは必要ありません。クエリの結果のコピーだけが必要です。

この特定のケースでは、9000が彼のコメントで示唆していることを実行する必要があります。カーソルの組み込み機能を使用して、リストの結果を取得します。これは、手動で呼び出すよりも高速である必要がありますlist

于 2012-04-16T14:09:59.923 に答える
0

余分な時間のデータのループを避けたい場合は、ジェネレーターでラップしてみてください。

def lazy_execute(sql, cursor=cursor):
    results = []
    cursor.execute(sql)
    def fetch():
        if results:
            for r in results:
                yield r
            raise StopIteration()
        else:
            for r in cursor:
                results.append(r)
                yield r
            raise StopIteration()

    return fetch

これにより、基本的に必要に応じてリストが作成されますが、同じ関数をどこでも安全に呼び出すことができます。次に、これを次のように使用します。

results = lazy_execute(my_sql):
for r in results():
    "do something with r"

これはほぼ間違いなく過剰に設計された時期尚早の最適化ですが、新しいリストを生成してから 2 つの異なる名前を持つ同じデータを生成するのではなく、同じ名前がすべての場合で同じことを意味するという利点があります。

これを使用することを主張する場合、データセットがかなり巨大でない限り、same-names 引数を使用すると思いますが、問題になるほど巨大な場合は、すべてを保存したくない可能性が高くなります。とにかく記憶。

また、それは完全にテストされていません。

于 2012-04-16T15:16:47.683 に答える