Значения базы данных возвращаются обратно после session.commit () - PullRequest
0 голосов
/ 17 июня 2020

У меня проблема, когда некоторые данные возвращаются к исходным значениям после вызова session.commit (). Вот код, который я запускаю в настоящее время:

def delete_source(source_id):
    source = Source.query.get_or_404(source_id)
    tasks = Task.query.all()

    log.info_print(f"source_id = {source_id}")

    log.info_print(f"Before commit [1]: {tasks}")

    for task in tasks:
        if source_id in task.source:
            task.source.remove(source_id)

    log.info_print(f"Before commit [2]: {tasks}")
    db.session.delete(source)   

    db.session.commit()
    log.info_print(f"After commit [1]: {tasks}")

И результат такой:

source_id = 42
Before commit [1]: [Task('ID: 1', 'Source: [42, 15]')]
Before commit [2]: [Task('ID: 1', 'Source: [15]')]
After commit [1]: [Task('ID: 1', 'Source: [42, 15]')]

Примечание о цели здесь ... когда этот маршрут вызывается, он удаляет элемент с source_id из таблицы исходной базы данных, используя db.session.delete(source), однако это все равно оставляет source_id в таблице задач (в частности, в исходном массиве), поэтому у меня есть for task in tasks l oop, который удаляет это из исходного массива.

Успешное удаление значения из массива, как показано в записи журнала Before commit [2]. Но потом почему-то возвращается. Но удаленный источник этого не делает (чего, конечно, не должно быть!)

С нетерпением жду предложений! Спасибо!

1 Ответ

0 голосов
/ 17 июня 2020

Я просмотрел документацию, но я не слишком хорошо знаком с sqlalchemy, поэтому я не нашел много. Одна теория состоит в том, что объект Query, созданный tasks = Task.query.all(), обнаружил, что вы зафиксировали новые изменения в базе данных, и автоматически пересчитал tasks при следующем использовании - в данном случае, когда вы распечатали его в это сообщение журнала после фиксации. В этом вновь сгенерированном tasks, возвращенном из базы данных, будет сохранен удаленный источник в его исходном массиве.

Один параметр, который я нашел для Session объектов, назывался expire_on_commit. Документы для Session.commit() говорят (выделено мной):

По умолчанию сеанс также истекает все загруженное состояние базы данных для всех атрибутов, управляемых ORM, после фиксации транзакции. Это позволяет при последующих операциях загружать самые свежие данные из базы данных. Это поведение можно отключить с помощью параметра expire_on_commit = False для создателя сеанса или конструктора сеанса.

Я Не уверен, что ссылка на результат Query считается «последующей транзакцией», но это возможно. Как я уже сказал, я не очень разбираюсь в sqlalchemy, поэтому этот флаг может не иметь отношения к этой конкретной ситуации, и вся эта теория пересчета tasks может быть совершенно неосновательной, но я подумал, что ' d поделиться тем, что я нашел, на случай, если это окажется полезным.

Подробнее о сеансе и методе фиксации можно узнать здесь: https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy .orm.session.Session.commit

...