我使用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.
答案 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")