I am trying to do an upsert statement and have the query return the updated values. On inserts, it works fine because there is no data but when there is an update, the query returns the old data that is getting updated.
This is my upsert statement-
def upsert(model, data, constraints):
insert_stmt: Insert = insert(model).values(data)
do_update_stmt = insert_stmt.on_conflict_do_update(
index_elements=constraints,
set_=data,
)
return do_update_stmt
I execute it and get the values like this-
upsert_query = upsert(
model,
new_data,
["constraint"],
)
try:
upsert_response = db.session.execute(
upsert_query.returning(model)
)
updated_model = upsert_response.fetchone()[0]
The issue is that updated_model here returns the old data. I can commit the query and it would give me the updated data as the model is changed but in my specific use case, I don't want to commit until more code after the above is ran and if the following code fails to execute I want to rollback. Unfortunately, I can't seem to get the rollback to happen after I commit.
My question is; is there a way to get the updated data from the response here instead on updates? If not, how can I rollback this commit? db is a SqlAlchemy() instance that is shared across the app.
When returning ORM objects you have to populate existing objects otherwise they will not be updated.
There is an example here:
using-returning-with-upsert-statements
Here is another example I made
The key line is