加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – sqlalchemy在yield_per期间发生游标错误

发布时间:2020-12-16 23:29:54 所属栏目:Python 来源:网络整理
导读:我收到以下错误: 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._fet
我收到以下错误:
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)

任何想法?

解决方法

如果没有从DBAPI游标中获取所有行,那么在该游标的连接上调用commit()通常是一个坏主意.在这种情况下,psycopg2(我猜测这是您所在的DBAPI)无法维护命名游标的状态(这是当您需要服务器缓冲行时)在事务中使用的状态.

你应该在这里改变一件事是你提交的频率.理想情况下,在整个操作完成之前,您不会提交任何内容.会话将根据需要自动刷新数据(如果您打开自动冲洗,我建议您),或者您可以调用flush()来强制它,但这与实际提交事务无关.所有这些对commit()的调用将使操作的效率要低于它所必须的效率,当然它会阻碍其他结果集的游标.如果你刚刚把一个commit()放在你的循环的末尾,那么你可以一次解决这两个问题.

如果您仍然需要在整个操作完成之前提交,或者即使不是这样,那么我更喜欢使用块而不是使用yield_per(),这是非常脆弱的. http://www.sqlalchemy.org/trac/wiki/UsageRecipes/WindowedRangeQuery的食谱显示了一种方法.尽管psycopg2给我们一个更大的回旋余地,但DBAPI并不适合处理非常大的结果集.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读