pyscopg2 无事务

问题描述 投票:0回答:2

有时我需要从 psycopg2 执行一个查询,该查询不在事务块中。

例如:

cursor.execute('create index concurrently on my_table (some_column)')
不起作用:

InternalError: CREATE INDEX CONCURRENTLY cannot run inside a transaction block
我没有看到任何简单的方法可以使用 psycopg2 来做到这一点。  我错过了什么?

我可能可以调用

os.system('psql -c "create index concurrently"')

 或类似的东西来让它从我的 python 代码中运行,但是如果能够在 python 中执行此操作而不依赖于 psql 实际上在容器中,那就更好了。

是的,对于这个特定的用例,我必须使用

concurrently

 选项。


另一次我对此进行了探索,但没有找到明显的答案,那就是当我有一组 sql 命令,我想用单个

execute()

 来调用,其中第一个命令会短暂锁定资源。  当我这样做时,该资源将在 
execute()
 的整个持续时间内保持锁定状态,而不是仅在 sql 字符串中的第一个语句运行时保持锁定状态,因为它们都在一个大的快乐事务中一起运行。

在这种情况下,我可以将查询分解为一系列execute() 语句 - 每个语句都成为自己的事务,这是可以的。

似乎应该有办法,但我似乎想念它。 希望这对某人来说是一个简单的答案。


编辑:添加代码示例:

#!/usr/bin/env python3.10 import psycopg2 as pg2 # -- set the standard psql environment variables to specify which database this should connect to. # We have to set these to 'None' explicitly to get psycopg2 to use the env variables connDetails = {'database': None, 'host': None, 'port': None, 'user': None, 'password': None} with (pg2.connect(**connDetails) as conn, conn.cursor() as curs): conn.set_session(autocommit=True) curs.execute(""" create index concurrently if not exists my_new_index on my_table (my_column); """)
投掷:

psycopg2.errors.ActiveSqlTransaction: CREATE INDEX CONCURRENTLY cannot run inside a transaction block
    
python psycopg2
2个回答
4
投票
根据 psycopg2 文档:

可以将连接设置为自动提交模式:这样所有执行的命令都将立即提交,并且不可能回滚。一些命令(例如使用事务控制对存储过程进行 CREATE DATABASE、VACUUM、CALL...)需要在任何事务之外运行:为了能够从 Psycopg 运行这些命令,连接必须处于自动提交模式:您可以使用自动提交属性。

因此关于连接:

conn.set_session(autocommit=True)


来自 psycopg2 文档的更多资源:

交易控制

连接.自动提交


0
投票
总结和澄清,工作答案是:

#!/usr/bin/env python3.10 import psycopg2 as pg2 # -- set the standard psql environment variables to specify # -- which database this should connect to. # We have to set these to 'None' explicitly to get psycopg2 to use the env variables conn_args = {'database': None, 'host': None, 'port': None, 'user': None, 'password': None} conn = pg2.connect(**conn_args) conn.set_session(autocommit=True) with conn.cursor() as curs: curs.execute(""" create index concurrently if not exists my_new_index on my_table(my_column); """) conn.close()
    
© www.soinside.com 2019 - 2024. All rights reserved.