2009-09-05 4 views
26

У меня есть последовательность новых объектов. Все они похожи похожи на это:sqlalchemy простой способ вставить или обновить?

Foo (pk_col1 = х, pk_col2 = у, вал = «бар»)

Некоторые из них являются Foo, которые существуют (т.е. только вал отличается от строки в БД) и должен генерировать запросы обновления. Другие должны создавать вставки.

Я могу придумать несколько способов сделать это, самое лучшее существо:

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

Есть ли более простой способ?

+0

Это похоже на дубликат http://stackoverflow.com/questions/708762/sqlalchemy-insert-or-replace-equivalent или http://stackoverflow.com/questions/1330475/how-do-efficiently -do-a-bulk-insert-or-update-with-sqlalchemy –

+1

@Duffy - Не тот же вопрос, как мне на самом деле нужно различать в python обновления от вставок, я не могу сделать это в базе данных с помощью не- -пространственное расширение SQL. – Eloff

ответ

36

Я думаю, что вы после new_obj = session.merge(obj). Это приведет к объединению объекта в отдельном состоянии в сеанс, если первичные ключи совпадают, и в противном случае он сделает новый. Таким образом, session.save(new_obj) будет работать как для вставки, так и для обновления.

+8

'' session.save() '' похоже, больше не существует в новых версиях sqlalchemy. –

-3
Session.save_or_update(model) 
+9

save_or_update устарел с 0,5 или около того. Он не будет работать, так как все новые объекты будут выглядеть одинаково для sqlalchemy (возможно, он будет выпускать обновления). Я не думаю, что он будет выдавать запросы, чтобы увидеть, что на самом деле существует в первую очередь. – Eloff

+3

Протестировано, и sqlalchemy делает все INSERTS, а затем barfs с ошибкой целостности существующих объектов. – Eloff