Ну, вопрос в значительной степени обобщает его. Моя активность в БД очень интенсивно обновляется, и я хочу программно выполнить вакуумный анализ. Однако я получаю сообщение об ошибке, в котором говорится, что запрос не может быть выполнен в рамках транзакции. Есть ли другой способ сделать это?
Можно ли выполнить VACUUM ANALYZE ‹tablename› из psycopg2 или sqlalchemy для PostgreSQL?
Ответы (2)
Это недостаток Python DB-API: он запускает транзакцию за вас. Этого делать не следует; следует ли и когда начинать транзакцию, зависит от программиста. Низкоуровневые основные API, подобные этому, не должны нянчиться с разработчиком и делать такие вещи, как запуск транзакций за нашей спиной. Мы большие мальчики - мы можем начать сделки сами, спасибо.
С помощью psycopg2 вы можете отключить это нежелательное поведение с помощью расширения API: запустите connection.autocommit = True
. К сожалению, для этого нет стандартного API, поэтому вам приходится полагаться на нестандартные расширения для выдачи команд, которые должны выполняться вне транзакции.
Ни один язык не без недостатков, и это один из недостатков Python. Я тоже был укушен этим раньше.
connection.autocommit
является логическим атрибутом, а не функцией. Таким образом, для выполнения запросов вне транзакции вы можете установить connection.autocommit = True
перед выполнением VACUUM.
- person Manuel G; 22.03.2015
session.commit()
мы находимся в новой транзакции. Это полностью противоречит тому, как работает begin; ...statements; commit;
.
- person kevlarr; 01.06.2020
Вы можете включить режим Postgres autocommit
с помощью SQLAlchemy raw_connection (что даст вам «сырое» соединение 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")