Можно ли выполнить VACUUM ANALYZE ‹tablename› из psycopg2 или sqlalchemy для PostgreSQL?

Ну, вопрос в значительной степени обобщает его. Моя активность в БД очень интенсивно обновляется, и я хочу программно выполнить вакуумный анализ. Однако я получаю сообщение об ошибке, в котором говорится, что запрос не может быть выполнен в рамках транзакции. Есть ли другой способ сделать это?


person donatello    schedule 14.10.2010    source источник
comment
возможный дубликат PostgreSQL - как запустить VACUUM из кода снаружи блокировка транзакции?   -  person Milen A. Radev    schedule 14.10.2010
comment
Спасибо, это дубликат. Как я могу отметить его как один?   -  person donatello    schedule 17.10.2010


Ответы (2)


Это недостаток Python DB-API: он запускает транзакцию за вас. Этого делать не следует; следует ли и когда начинать транзакцию, зависит от программиста. Низкоуровневые основные API, подобные этому, не должны нянчиться с разработчиком и делать такие вещи, как запуск транзакций за нашей спиной. Мы большие мальчики - мы можем начать сделки сами, спасибо.

С помощью psycopg2 вы можете отключить это нежелательное поведение с помощью расширения API: запустите connection.autocommit = True. К сожалению, для этого нет стандартного API, поэтому вам приходится полагаться на нестандартные расширения для выдачи команд, которые должны выполняться вне транзакции.

Ни один язык не без недостатков, и это один из недостатков Python. Я тоже был укушен этим раньше.

person Glenn Maynard    schedule 14.10.2010
comment
просто комментарий о том, что connection.autocommit является логическим атрибутом, а не функцией. Таким образом, для выполнения запросов вне транзакции вы можете установить connection.autocommit = True перед выполнением VACUUM. - person Manuel G; 22.03.2015
comment
Да, я не могу согласиться с этим больше. Нелепо, что после 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")
person mdh    schedule 28.01.2017