我有很多子对象要添加到父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锁定以确保它们不会阻止它以及活动(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()
答案 0 :(得分:0)
我找到了解决方案,它是.values(list_of_dictionaries)
调用导致问题。这有效:
eng = DBSession.get_bind()
eng.execute(rbrf_table.insert(), lines)
eng.dispose()