У меня есть 2 метода API, один из которых - пометить запись как removed
и обновить базу данных следующим кодом:
record = DBSession.query(MyModel).filter_by(id=something_id).first()
if not saved_search:
return {"error": "not_found"}
with transaction.manager:
# for demonstration I toggle the removed flag
record.removed = not record.removed
DBSession.add(record)
return {}
Каждый раз, когда я вызываю эту конечную точку, она фиксирует изменения в базе данных и Я вижу изменения на стороне БД. Проблема возникает, когда я вызываю приведенный ниже метод обновления и пытаюсь что-то изменить в БД:
record = DBSession.query(MyModel).filter_by(
id=update_id,
removed=False
).first()
if not record:
return { "error": "not_found"}
data = request.get_json(force=True)
try:
with transaction.manager:
if data.get('is_default'):
DBSession.query(MyModel). \
filter_by(user_id=USER_ID) \
.update({MyModel.is_default: False})
record.is_default = data.get('is_default', record.is_default)
record.name = data.get('name', record.name)
DBSession.add(record)
except Exception:
DBSession.rollback()
return {"error": "duplicate_name"}
Приведенный выше метод обновления сначала находит идентификатор записи, где он не равен removed
. Затем устанавливает все предыдущие записи для этого пользователя в false, поскольку у нас есть одна запись по умолчанию, а не несколько. Затем обновите name
записи и is_default
поля.
Моя примерная модель данных выглядит следующим образом:
id=UUID
user_id=UUID
name=string
is_default=boolean
removed=boolean
Как я объяснил, когда я отмечаю запись как удаленную столько раз как я хочу нет проблем. Теперь, когда удалено значение false
, и я обновляю запись с новым именем после вызова метода удаления (помечая запись как удаленную), тогда эти данные присутствуют в сеансе, а не в базе данных (теперь я вижу изменения, используя python debug), когда я вызовите delete
метод, он не сохраняется в базе данных.
Почему я попадаю в это несовместимое состояние и данные не сбрасываются в БД при вызове update после удаления?
У меня есть уникальное ограничение в таблице на user_id, name
. Когда возникает исключение IntegrityError, я откатываю процесс обновления. Такое несоответствие обычно возникает при возникновении ошибки двойственности.