有时我需要从 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
选项。
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
#!/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()