TravisVOX
TravisVOX

Reputation: 21631

SQLAlchemy Core - INSERT IGNORE and ON DUPLICATE KEY UPDATE

I'm using SQLAlchemy Core with a MySQL database but am having a hard time finding a solution for INSERT IGNORE / DUPLICATE KEY UPDATE. I hate to write a one-off query manually in the code if there's a way to handle this. Most solutions or discussions I've found center around the ORM, but not the core. And even some of those are dead links. Is it even possible?

Upvotes: 16

Views: 27798

Answers (4)

buxizhizhoum
buxizhizhoum

Reputation: 1929

Another method is:

stmt = YourModel.__table__.insert().prefix_with(" ignore").values(data)
session.execute(stmt)

Upvotes: 1

codelover
codelover

Reputation: 44

SQL Mode


print '--------- test upsert --------------'
for r in rows:
    r['value'] = r['id'] + 1

sql = '''
    INSERT INTO test (id, value)
    VALUES (:id, :value)
    ON DUPLICATE KEY UPDATE value = VALUES(value)
'''
start = time.time()
engine.execute(text(sql), rows)

Upvotes: 0

shaktimaan
shaktimaan

Reputation: 1857

I know it is a bit late.. but if someone is still looking for solutions.

FOR: ON DUPLICATE KEY UPDATE

ins = insert(/* table_name*/ ).values(/*your values(with PK)*/)
do_update_stmt = ins.on_duplicate_key_update(/*your values(with out PK)*/)
connection.execute(do_update_stmt)

On duplicate key update docs

The ON DUPLICATE KEY UPDATE clause of INSERT supported by MySQL is now supported using a MySQL-specific version of the Insert object

This wont be avaliable with sqlalchemy.insert().

FOR: INSERT IGNORE

This is a bit hacky but works just fine.

 ins_address_stmt = insert(/* table_name*/ ).values(/*your values*/). \
            prefix_with('IGNORE')

Insert prefix_with

MySQL will suppress the error for duplicate primary key and gives a warning.

Upvotes: 22

Bryan
Bryan

Reputation: 194

shaktimaan's answer works great for MySQL INSERT IGNORE. If you found this page looking for SQLite INSERT IGNORE, remember to do INSERT OR IGNORE

https://www.sqlite.org/lang_insert.html

stmt = insert(/* table_name*/ ).values(/*your values*/).prefix_with('OR IGNORE')

Upvotes: 11

Related Questions