Как использовать PRAGMA с новым атрибутом autocommit sqlite3 в Python?Python

Программы на Python
Ответить
Anonymous
 Как использовать PRAGMA с новым атрибутом autocommit sqlite3 в Python?

Сообщение Anonymous »

Недавно в модуле Python sqlite3 появился атрибут autocommit, для которого в документации рекомендуется установить значение False. Я хотел бы использовать этот рекомендуемый параметр для нового проекта, использующего Python 3.12. Однако я также хотел бы обеспечить соблюдение ограничений внешнего ключа в моей базе данных. Я знаю, что для этого требуется настройка Connection.execute("PRAGMA Foreign_keys = ON;") для каждого соединения. Это работает при использовании опции по умолчанию для автофиксации, а именно LEGACY_TRANSACTION_CONTROL. При использовании autocommit=False (как рекомендуется) ограничения внешнего ключа больше не применяются. Если я правильно понимаю, это связано с тем, что PRAGMA работает только в том случае, если ни одна транзакция не активна, но autocommit=False всегда неявно открывает транзакцию, как описано в документации.
Я обнаружил, что работает следующее:
con = sqlite3.connect(path, autocommit=True)
con.execute("PRAGMA foreign_keys = ON;")
con.autocommit = False

Теперь мой вопрос: это предполагаемое поведение sqlite3 или ошибка? Если это так, является ли приведенный выше обходной путь лучшим способом решить эту проблему и есть ли при этом какие-либо скрытые последствия, которые приводят к другому поведению по сравнению с установкой autocommit=False непосредственно в вызове Connect()? Я удивлен, что ничего из этого нигде не задокументировано, я предполагаю, что проверки внешнего ключа довольно часто желательны...
Вот полный минимальный рабочий пример всего этого:
import sqlite3

# con = sqlite3.connect(":memory:", autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL) # PRAGMA works
# con = sqlite3.connect(":memory:", autocommit=False) # PRAGMA doesn't work
con = sqlite3.connect(":memory:", autocommit=True) # PRAGMA works, but need to set autocommit=False afterwards
con.execute("PRAGMA foreign_keys = ON;")
con.autocommit = False

# Super basic two-table example...
con.execute("CREATE TABLE foo(id INTEGER PRIMARY KEY, baz TEXT UNIQUE)")
con.execute("CREATE TABLE bar(id INTEGER PRIMARY KEY, bazid INTEGER UNIQUE,"
"FOREIGN KEY (bazid) REFERENCES foo (id))")

# Insert some values so a foreign key exists
with con:
con.execute("INSERT INTO foo(baz) VALUES(?)", ("spam",))
con.execute("INSERT INTO foo(baz) VALUES(?)", ("eggs",))

# This should pass
with con:
con.execute("INSERT INTO bar(bazid) VALUES(?)", ("1",))

# This should fail
with con:
con.execute("INSERT INTO bar(bazid) VALUES(?)", ("42",))

con.close()
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»