SQLAlchemy 核心插入使(金字塔)作用域会话挂起
SQLAlchemy Core inserts make (Pyramid) scoped session hanging
我有很多子对象要添加到父 SQA 对象,有时有 10,000 个左右。代码在 Pyramid 应用程序中运行,它使用范围会话和 ZopeTransactionExtension
:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
这没有问题:
lines = [{'col1':1, 'col2':2, 'related_id':1}, ...]
for d in lines:
d['related_id'] = related_id
f = SQAObject(**d)
DBSession.add(f)
为了性能,我使用 SQLAlchemy Core insert
s:
重写了这个
lines = [{'col1':1, 'col2':2, 'related_id':1}, ...]
rbrf_table = SQAObject.__table__
eng = DBSession.get_bind()
conn = eng.connect()
for d in lines:
d['related_id'] = related_id
conn.execute(rbrf_table.insert().values(lines))
conn.close()
eng.dispose()
这导致了一个比较奇怪的问题:代码执行(更快),但是HTTP请求完成后,结果没有返回给HTTP客户端。相反,Python 进程无限期地消耗 100% CPU(我等了半个小时以确保它是否在任何时候完成)。
我检查了 Postgres 锁以确保它们不会像 activity (select * from pg_stat_activity
) 那样阻止它,但似乎没有任何异常。
这个问题可能是什么原因造成的?
P.S。怀疑处理引擎可能会导致此问题,我 运行 使用和不使用 eng.dispose()
的相同代码,结果相同。
更新
剧情变厚了。如果我改为执行单独的插入,它会起作用:
rbrf_table = RTABomRowFile.__table__
eng = DBSession.get_bind()
conn = eng.connect()
for d in lines:
...
ins = rbrf_table.insert().values(d)
conn.execute(ins)
conn.execute('COMMIT')
conn.close()
eng.dispose()
我找到了解决方案,是 .values(list_of_dictionaries)
调用导致了问题。这有效:
eng = DBSession.get_bind()
eng.execute(rbrf_table.insert(), lines)
eng.dispose()
我有很多子对象要添加到父 SQA 对象,有时有 10,000 个左右。代码在 Pyramid 应用程序中运行,它使用范围会话和 ZopeTransactionExtension
:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
这没有问题:
lines = [{'col1':1, 'col2':2, 'related_id':1}, ...]
for d in lines:
d['related_id'] = related_id
f = SQAObject(**d)
DBSession.add(f)
为了性能,我使用 SQLAlchemy Core insert
s:
lines = [{'col1':1, 'col2':2, 'related_id':1}, ...]
rbrf_table = SQAObject.__table__
eng = DBSession.get_bind()
conn = eng.connect()
for d in lines:
d['related_id'] = related_id
conn.execute(rbrf_table.insert().values(lines))
conn.close()
eng.dispose()
这导致了一个比较奇怪的问题:代码执行(更快),但是HTTP请求完成后,结果没有返回给HTTP客户端。相反,Python 进程无限期地消耗 100% CPU(我等了半个小时以确保它是否在任何时候完成)。
我检查了 Postgres 锁以确保它们不会像 activity (select * from pg_stat_activity
) 那样阻止它,但似乎没有任何异常。
这个问题可能是什么原因造成的?
P.S。怀疑处理引擎可能会导致此问题,我 运行 使用和不使用 eng.dispose()
的相同代码,结果相同。
更新
剧情变厚了。如果我改为执行单独的插入,它会起作用:
rbrf_table = RTABomRowFile.__table__
eng = DBSession.get_bind()
conn = eng.connect()
for d in lines:
...
ins = rbrf_table.insert().values(d)
conn.execute(ins)
conn.execute('COMMIT')
conn.close()
eng.dispose()
我找到了解决方案,是 .values(list_of_dictionaries)
调用导致了问题。这有效:
eng = DBSession.get_bind()
eng.execute(rbrf_table.insert(), lines)
eng.dispose()