Почему изменения сеанса SQLAlchemy не фиксируют изменения в базе данных? - PullRequest
0 голосов
/ 21 марта 2020

У меня есть 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, я откатываю процесс обновления. Такое несоответствие обычно возникает при возникновении ошибки двойственности.

...