views:

1384

answers:

2

I have a sequence of new objects. They all look like similar to this:

Foo(pk_col1=x, pk_col2=y, val='bar')

Some of those are Foo that exist (i.e. only val differs from the row in the db) and should generate update queries. The others should generate inserts.

I can think of a few ways of doing this, the best being:

pk_cols = Foo.table.primary_key.keys()
for f1 in foos:
    f2 = Foo.get([getattr(f1, c) for c in pk_cols])
    if f2 is not None:
        f2.val = f1.val # update
        # XXX do we need to do session.add(f2) 
        # (or at least keep f2 alive until after the commit?)
    else:
        session.add(f1) # insert

 session.commit()

Is there an easier way?

+1  A: 
Session.save_or_update(model)
nosklo
save_or_update has been deprecated since 0.5 or so. It won't work as all the new objects will look the same to sqlalchemy (probably it will issue updates) I do not think it will issue queries to see which actually exist first.
Eloff
Tested it and sqlalchemy does all INSERTS and then barfs with an integrity error on existing objects.
Eloff
+1  A: 

I think you are after new_obj = session.merge(obj). This will merge an object in a detached state into the session if the primary keys match and will make a new one otherwise. So session.save(new_obj) will work for both insert and update.

David Raznick