#sqlite #flask #error-handling #transactions
Вопрос:
Я пытаюсь создать несколько интеллектуальных сообщений об ошибках с помощью функции @app.errorhandler (500). Например, мой маршрут включает команду ВСТАВКИ в базу данных:
if request.method == "POST":
userID = int(request.form.get("userID"))
topicID = int(request.form.get("topicID"))
db.execute("BEGIN TRANSACTION")
db.execute("INSERT INTO UserToTopic (userID,topicID) VALUES (?,?)", userID, topicID)
db.execute("COMMIT")
Если эта транзакция нарушает ограничение, такое как УНИКАЛЬНЫЙ или ВНЕШНИЙ ключ, я хочу поймать ошибку и отобразить удобное для пользователя сообщение. Для этого я использую Flask @app.errorhandler следующим образом:
@app.errorhandler(500)
def internal_error(error):
db.execute("ROLLBACK")
return render_template('500.html'), 500
Команда «ОТКАТ» отлично работает, если я нахожусь в середине транзакции базы данных. Но иногда ошибка 500 не связана с базой данных, и в этих случаях сам оператор ОТКАТА вызывает ошибку, потому что вы не можете откатить транзакцию, которая никогда не запускалась. Поэтому я ищу метод, который возвращает логическое значение, которое было бы истинным, если выполняется транзакция бд, и ложным, если нет, поэтому я могу использовать его, чтобы сделать откат условным. Единственное, что я могу найти в документации SQLite3, — это интерфейс C, и я не могу заставить его работать с моим кодом Python. Есть какие-нибудь предложения?
Я знаю, что если я буду достаточно осторожен со своими формами и маршрутами, я смогу предотвратить 99% потенциальных нарушений правил БД. Но я все равно хотел бы, чтобы умный ловец ошибок защитил меня от остальных 1%.
Ответ №1:
Я не знаю, как работает транзакция в sqlite, но то, что вы пытаетесь сделать, вы можете достичь с помощью операторов try/except
- используйте try/за исключением внутри функции
try:
db.execute("ROLLBACK")
except:
pass
return render_template('500.html'), 500
- Используйте try/за исключением случаев, когда вставляете данные.
from flask import abort
try:
userID = int(request.form.get("userID"))
[...]
except:
db.rollback()
abort(500)
Я не знаком с ошибками sqlite, если вы знаете, какая конкретная ошибка возникает, за исключением этой конкретной ошибки.