我的数据库活动更新密集,我想以编程方式发出 Vacuum 分析。
但是,我收到一条错误,指出查询无法在事务中执行。
还有其他方法吗?
这是 Python DB-API 中的一个缺陷:它为您启动一个事务。 它不应该这样做;是否以及何时开始事务应该由程序员决定。 像这样的低级核心 API 不应该照顾开发人员并在我们背后执行诸如启动事务之类的事情。 我们是大男孩了——我们可以自己开始交易,谢谢。
使用 psycopg2,您可以通过 API 扩展禁用这种不幸的行为:运行
connection.autocommit = True
。 不幸的是,没有标准的 API 可以实现这一点,因此您必须依赖非标准扩展来发出必须在事务外部执行的命令。
没有一种语言是没有缺点的,Python 就是其中之一。 我以前也被这个咬过。
您可以使用 SQLAlchemy 的
raw_connection打开 Postgres
autocommit
模式(这将为您提供“原始”psycopg2 连接):
import sqlalchemy
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
engine = sqlalchemy.create_engine(url)
connection = engine.raw_connection()
connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
cursor = connection.cursor()
cursor.execute("VACUUM ANALYSE table_name")
不确定旧版本的 SQLAlchemy,但使用最新版本(1.4.x 或更高版本),您可以创建自动提交会话,而无需处理原始连接或依赖于数据库特定的 hack:
import sqlalchemy
from sqlalchemy.orm import Session
engine = sqlalchemy.create_engine('postgresql://localhost:5432')
autocommit_engine = engine.execution_options(isolation_level="AUTOCOMMIT")
with Session(autocommit_engine) as session:
session.execute(f'VACUUM ANALYZE public.my_table;')
自动提交引擎可以从任何
Engine
对象派生。旧的 Engine
实例仍保持功能。