문제

I have a portion of the code which does the following:

  • get the data from the database
  • perform an API call to one server
  • perform another API call to another server
  • store the results in the database (new data and change of existing ones)

Now, when getting the results from the database, there is specific order of things that need to be happened. When the calls are performed, the invoice should be created with, lets say, length, which is equal to the current one and the one obtained from the API. That same length should be changed on the data obtained from the database (customer).

Second API call sometimes "fails", in a sense that a transaction is not approved, so the most of the process shall not happen: invoice creation, modification of most data entries. The one entry that should be generated is the failure message, stored in the db, which contains the data obtained from query (id, length and so on).

So, I have tried to solve this via try/except, in pseudocode:

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()

Everything works OK when the API calls are successfull. When the second one fails, I still need a DB entry, but since I have already changed the data for existing data (customer, group), added things to session, those get added by the last commit in the except clause as well, which is not what I want. I need only the newClassOne and some data, like ID of customer obtained in the try clause.

I have found rollback() and some similarmethods, but can't figure out which one should I use, as I have been relatively new to sqlalchemy and the session storage, and documentation seems a bit too complicated for my level of knowledge there.

Thanks

도움이 되었습니까?

해결책

I handled this question by reordering how are things executed during the code:

  • first API call, if it fails, it breaks the cycle and creates a failure entry in the DB
  • second API call, if it fails, it creates a notice and generates a different code, but the loop continues
  • update of existing entries
  • committing changes to the database
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top