一千萬個為什麽

搜索

SQLAlchemy ON DUPLICATE KEY UPDATE

是否有一種優雅的方法在SQLAlchemy中執行 INSERT ... ON DUPLICATE KEY UPDATE ?我的意思是語法類似於 inserter.insert()。execute(list_of_dictionaries)

最佳答案

ON DUPLICATE KEY UPDATE in the SQL statement

如果您希望生成的SQL實際包含 ON DUPLICATE KEY UPDATE ,最簡單的方法是使用 @compiles 裝飾器。

代碼(鏈接來自主題上的一個好主題 on reddit )例如,可以在github上找到

from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Insert

@compiles(Insert)
def append_string(insert, compiler, **kw):
    s = compiler.visit_insert(insert, **kw)
    if 'append_string' in insert.kwargs:
        return s + " " + insert.kwargs['append_string']
    return s


my_connection.execute(my_table.insert(append_string = 'ON DUPLICATE KEY UPDATE foo=foo'), my_values)

但請註意,在此方法中,您必須手動創建append_string。您可以更改append_string函數,以便它自動將插入字符串更改為帶有“ON DUPLICATE KEY UPDATE”字符串的插入,但由於懶惰,我不打算這樣做。

ON DUPLICATE KEY UPDATE functionality within the ORM

SQLAlchemy不提供 ON DUPLICATE KEY UPDATEMERGE 或其ORM層中的任何其他類似功能的接口。不過,它有 session.merge() 功能只有在相關密鑰是主鍵時才能復制功能

session.merge(ModelObject) first checks if a row with the same primary key value exists by sending a SELECT query (or by looking it up locally). If it does, it sets a flag somewhere indicating that ModelObject is in the database already, and that SQLAlchemy should use an UPDATE query. Note that merge is quite a bit more complicated than this, but it replicates the functionality well with primary keys.

但是,如果您希望 ON DUPLICATE KEY UPDATE 功能與非主鍵(例如,另一個唯一鍵),該怎麽辦?不幸的是,SQLAlchemy沒有任何這樣的功能。相反,你必須創建類似於Django的 get_or_create()的東西。 另一個StackOverflow答案涵蓋了它,為了方便起見,我將在此處粘貼修改後的工作版本。

def get_or_create(session, model, defaults=None, **kwargs):
    instance = session.query(model).filter_by(**kwargs).first()
    if instance:
        return instance
    else:
        params = dict((k, v) for k, v in kwargs.iteritems() if not isinstance(v, ClauseElement))
        if defaults:
            params.update(defaults)
        instance = model(**params)
        return instance

轉載註明原文: SQLAlchemy ON DUPLICATE KEY UPDATE