Reputation: 21473
I essentially need to do an INSERT ... ON DUPLICATE KEY UPDATE
however the row will already exist 99.9...% of the time. Therefore, what I really want to do is an UPDATE
, catch the odd exception and INSERT
.
In sqlalchemy I would typically do the following:
new_obj = MyModel(the_pk=id)
new_obj = MyModel.__table__.c.some_val + val
session.merge(new_obj)
I noticed though that when I call session.merge
sqlalchemy does a SELECT
, which is inefficient in the case that I know I'm almost always UPDATE
'ing. Is there some way to improve on this short of just writing raw SQL (which I'm fine with)? I was just wondering if there was some sqlalchemy trick I'm missing.
Also, after doing the merge, what happens if a row with a conflicting PK comes into existence before the session is flushed/committed? I assume the select is to determine if sqlalchemy needs to later do an INSERT
or UPDATE
Upvotes: 0
Views: 1132
Reputation: 2489
Couple options: 1) Bypass SA and do an actual merge statement or use a replace statement if your dbms supports it. Here is an SA ticket for adding merge statement, which also includes a receipt for replace statement: SA Ticket 960
2) Easy way, do an update, you'll get the number of rows updated back, if it's 0 do the insert.
The 2nd option could potentially have issues if you have multiple writers since two writers could update and both get 0 rows updated back and then only one of the two writers inserts would succeeded. Not sure if that is an issue in your case but something to be aware of.
Upvotes: 1