sqlalchemy: как сделать транзакции sqlite немедленными?

#sqlite #sqlalchemy

#sqlite #sqlalchemy

Вопрос:

транзакции sqlite могут быть «отложенными», «немедленными» или «эксклюзивными». Значение по умолчанию «отложено», что означает, что транзакция не запускается до тех пор, пока это абсолютно необходимо. Это может привести к прерыванию транзакции, если параллельные транзакции начинаются с чтения, а затем переходят к записи. Таких прерываний можно избежать, используя немедленные транзакции (ценой снижения производительности).

sqlalchemy абстрагирует диалекты sql, включая sqlite. В нем также есть модель для записи транзакций:

 with engine.begin() as connection:
    do_something_with_connection
  

Как сообщить sqlalchemy, что такая транзакция должна быть немедленной. В качестве альтернативы, как сообщить sqlalchemy, что все транзакции sqlite должны быть немедленными?

Ответ №1:

Основные события https://docs.sqlalchemy.org/en/latest/core/events.html может использоваться для перехвата событий подключения и перезаписи инструкции BEGIN, выданной в начале транзакции, для достижения желаемого.

Смотрите раздел документации sqlalchemy на диалекте sqlite для получения более подробной информации https://docs.sqlalchemy.org/en/latest/dialects/sqlite.html.

Приведенный ниже пример кода скопирован непосредственно из документации, отличной от изменения BEGIN на BEGIN IMMEDIATE.

 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's 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 IMMEDIATE")
  

Комментарии:

1. Да, на этот вопрос есть полный ответ в документах. Оглядываясь назад, не очень хороший вопрос. Я не уверен, как я пропустил это при чтении документов, прежде чем задавать вопрос на этом этапе. Спасибо за точное объяснение. Должен ли я удалить вопрос?