Недавно в модуле 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()
Как использовать PRAGMA с новым атрибутом autocommit sqlite3 в Python? ⇐ Python
Программы на Python
1778804809
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()
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия