sqlalchemy核心流程仍然“在交易中闲置”

时间:2015-04-17 01:44:32

标签: transactions sqlalchemy core

我使用sqlAlchemy核心访问postgres数据库。我从中做出选择后,我有一个问题。查看CPU进程(ps -aux | grep postgres)我可以看到drop命令正在等待。它似乎正在等待select语句清除,这应该已经发生。我做了选择并处理了所有行,以便结束选择过程。我甚至试图关闭光标,但那并没有做任何事情。关于我唯一能做的就是关闭连接,但我认为我不得不为每个数据库查询重新建立一个连接,或者我应该这样做?

以下是关于坠落如何悬挂的基本概念。

engine = create_engine('postgresql://***:***@localhost:5432/Junk')
metadata = MetaData()
temp_table = Table('index_tmp', metadata,
                       Column('pid', Integer, primary_key = True),
                       Column('match_id', Integer),
                       Column('id', Integer)
                       )
people = Table('people', metadata, schema='public', autoload=True,          autoload_with=engine)

metadata.create_all(engine)
conn = engine.connect()

sel = select([func.min(people.c.id).label('match_id'), people.c.id])
ins = temp_table.insert().from_select(['match_id', 'id'], sel)
conn.execute(ins)

result = conn.execute(select([tmp_table]))
#Here the process shows "idle in transaction"

result.fetchall()
#This closes the cursor but the process is still "idle in transaction"

temp_table.drop(engine, checkfirst=True)
#The script will hang here since the select command is still "idle in  transaction" and blocking this drop.

1 个答案:

答案 0 :(得分:0)

很难从你的例子中看到问题是什么,但我希望变量被分配一个sqlalchemy.engine.result.ResultProxy对象,而不是收集的garbate。例如,这会创建两个挂起的事务:

one = engine.execute("select 1");
two = engine.execute("select 2");

...

test=# select state,query from pg_stat_activity where application_name != 'psql';
        state        |  query
---------------------+----------
 idle in transaction | select 1
 idle in transaction | select 2
(2 rows)

在您的示例中del(result)result.fetchall()result.close()都会发出ROLLBACK

您还可以通过指示SQLAlchemy / psycopg2不创建隐式事务来完全避免此行为:

engine = create_engine(uri, isolation_level="AUTOCOMMIT")