Удалить объекты из сеанса sqlalchemy

У меня есть часть кода, которая делает следующее:

  • получить данные из базы данных
  • выполнить вызов API к одному серверу
  • выполнить еще один вызов API на другой сервер
  • сохранять результаты в базе данных (новые данные и изменение существующих)

Теперь при получении результатов из базы данных необходимо выполнить определенный порядок действий. Когда вызовы выполняются, счет должен быть создан, скажем, с length, который равен текущему и полученному из API. Тот самый length должен быть изменен на данные, полученные из базы данных (заказчика).

Второй вызов API иногда «терпит неудачу» в том смысле, что транзакция не утверждается, поэтому большая часть процесса не происходит: создание счета, изменение большинства записей данных. Одна запись, которая должна быть сгенерирована, — это сообщение об ошибке, хранящееся в базе данных, которое содержит данные, полученные из запроса (идентификатор, длина и т. д.).

Итак, я попытался решить это с помощью try/except в псевдокоде:

try:
    customer = Customer.query.filer_by(id=1).first()
    group = Groups.query.filer_by(id=1).first()

    api_one_call() #returns the LENGTH
    customer.length = LENGTH
    group.quota += LENGTH

    invoice = generate_invoice(LENGTH)
    db.session.add(invoice)

    api_two_call(ID) #can suceed or fail, and returns ID

    newClassOne = ClassOne(ID)
    db.session.add(newClassOne)

    db.sesion.commit() #have to do this commit to have the id of the newClassOne as that one is included in the next db entry 

    newCLassTwo =ClassTwo(newClassOne.id)
    db.session.add(newClassOne)
    db.sesion.commit()
except:
    #potentially clean the session data there
    newClassOne = ClassOne(ID, faiture)
    db.session.add(newClassOne)
    db.sesion.commit()

Все работает нормально, когда вызовы API успешны. Когда второй терпит неудачу, мне все еще нужна запись в БД, но, поскольку я уже изменил данные для существующих данных (customer, group), добавил вещи в session, они также добавляются последней фиксацией в предложении кроме, что это не то, что я хочу. Мне нужен только newClassOne и некоторые данные, например ID customer, полученный в предложении try.

Я нашел rollback() и несколько подобных методов, но не могу понять, какой из них мне следует использовать, так как я был относительно новым для sqlalchemy и хранилища session, и документация кажется слишком сложной для моего уровня знаний.

Спасибо


person wont_compile    schedule 17.01.2014    source источник


Ответы (1)


Я решил этот вопрос, изменив порядок выполнения вещей во время кода:

  • первый вызов API, в случае сбоя он прерывает цикл и создает запись о сбое в БД
  • второй вызов API, в случае сбоя он создает уведомление и генерирует другой код, но цикл продолжается
  • обновление существующих записей
  • внесение изменений в базу данных
person wont_compile    schedule 19.01.2014