14

次のエラーが発生します。

Traceback (most recent call last):
    main()
    for item in session.query(Item).yield_per(10):
    fetch = cursor.fetchmany(self._yield_per)
    self.cursor, self.context)
    l = self.process_rows(self._fetchmany_impl(size))
    row = self._fetchone_impl()
    self.__buffer_rows()
    self.__rowbuffer = collections.deque(self.cursor.fetchmany(size))
sqlalchemy.exc.ProgrammingError: (ProgrammingError) named cursor isn't valid anymore None None

session.commit()の呼び出しが.yield_perに干渉していると思われます

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

def foo(item):
  # DO something to the item 
  session.add(item)
  session.commit()

def main():
  for item in session.query(Item).yield_per(5):
    foo(item)

何か案が?

4

3 に答える 3

18

DBAPIカーソルからすべての行をフェッチしていない場合は、通常、そのカーソルの接続でcommit()を呼び出すことはお勧めできません。この場合、psycopg2(これはあなたが使用しているDBAPIだと思います)は、トランザクション全体で名前付きカーソルの状態(サーバーバッファー行が必要な場合に使用するもの)を維持できません。

ここで間違いなく変更する必要があることの1つは、コミットする頻度です。理想的には、操作全体が完了するまで何もコミットしません。セッションは必要に応じてデータを自動的にフラッシュします(自動フラッシュをオンにした場合は、これをお勧めします)。または、flush()を呼び出して強制することもできますが、これは実際にトランザクションをコミットすることとは無関係です。commit()を呼び出すと、操作の効率が必要以上に低下します。もちろん、他の結果セットのカーソルの邪魔になります。ループの最後にcommit()を1つ置くだけで、両方の問題を一度に解決できます。

操作全体が完了する前にコミットする必要がある場合、またはそうでない場合でも、非常に脆弱なyield_per()を使用するよりも、チャンクで作業することをお勧めします。http://www.sqlalchemy.org/trac/wiki/UsageRecipes/WindowedRangeQueryのレシピは、これを行う1つの方法を示しています。DBAPIは、psycopg2によって少し余裕がありますが、全体として非常に大きな結果セットを処理するのにはあまり適していません。

于 2012-09-02T03:20:02.043 に答える
4

上記の問題は、もう1つのセッションで解決できます

sessionmaker_ = sessionmaker(autocommit=False, autoflush=False, bind=engine)
session = scoped_session(sessionmaker_)
cool_session = scoped_session(sessionmaker_)

def foo(item):
   # DO something to the item 
   session.add(item)
   session.commit()

def main():
    for item in cool_session.query(Item).yield_per(5):
    item = session.merge(item, load=False)
    foo(item)
于 2013-07-04T09:35:21.857 に答える
0

もう1つのオプションは、sqlalchemyリリースに入るときにカーソルオプション「WITHHOLD」を使用することです: https ://bitbucket.org/zzzeek/sqlalchemy/issues/3667/support-postgresqls-with-hold-cursor

スコットが最初のコミットでカーソルを実体化するPostgresについて言及している警告に注意してください。

于 2016-03-16T11:33:32.717 に答える