SQLAlchemy Core插入make(Pyramid)范围的会话

时间:2015-11-13 12:08:44

标签: python postgresql sqlalchemy pyramid pylons

我有很多子对象要添加到父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()

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,它是.values(list_of_dictionaries)调用导致问题。这有效:

eng = DBSession.get_bind()
eng.execute(rbrf_table.insert(), lines)
eng.dispose()