Ответ 1
Я столкнулся с этой проблемой, используя вложенные транзакции, используя Python 3 в Windows. Я использую SQLite версии 3.8.11, поэтому SAVEPOINT
должен поддерживаться. По-видимому, установка pysqlite для меня не является вариантом, поскольку она не поддерживает Python 3.
Через несколько часов, ударив головой о стол, я увидел этот раздел в документации:
В разделе "Поведение блокировки базы данных / Concurrency" мы ссылаемся на ассортимент драйверов pysqlite, которые предотвращают несколько возможности SQLite работать корректно. Драйвер pysqlite DBAPI имеет несколько давних ошибок, которые влияют на правильность его транзакционное поведение. В режиме работы по умолчанию SQLite такие функции, как изоляция SERIALIZABLE, DDL транзакции и Поддержка SAVEPOINT нефункциональна, и для использования этих функции, обходные пути должны быть приняты.
Проблема заключается в том, что драйвер пытается вторгаться в пользователи не могут начать транзакции и иногда заканчивают их преждевременно, чтобы свести к минимуму файл данных SQLite databasess хотя сам SQLite использует "общие" блокировки для только для чтения.
SQLAlchemy предпочитает не изменять это поведение по умолчанию, так как это долгожданное поведение драйвера pysqlite; если и когда Драйвер pysqlite пытается устранить эти проблемы, и это будет больше драйвер по умолчанию для SQLAlchemy.
Хорошей новостью является то, что с несколькими событиями мы можем реализовать полностью поддерживать транзакционную поддержку, полностью отключив функцию pysqlites и испуская НАЧАТЬ себя. Это достигается с помощью двух событий Слушатели:
from sqlalchemy import create_engine, event engine = create_engine("sqlite:///myfile.db") @event.listens_for(engine, "connect") def do_connect(dbapi_connection, connection_record): # disable pysqlite emitting of the BEGIN statement entirely. # also stops it from emitting COMMIT before any DDL. dbapi_connection.isolation_level = None @event.listens_for(engine, "begin") def do_begin(conn): # emit our own BEGIN conn.execute("BEGIN")
Добавление слушателей выше полностью разрешило проблему для меня!
Я опубликовал полный рабочий пример как сущность:
https://gist.github.com/snorfalorpagus/c48770e7d1fcb9438830304c4cca24b9
Я также обнаружил, что полезные предложения SQL полезны (это используется в приведенном выше примере):
Отладка (отображение) команды SQL, отправленной в db по SQLAlchemy