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?
Asked
Active
Viewed 2.1k times
13
-
Very much related: https://stackoverflow.com/questions/6611563/sqlalchemy-on-duplicate-key-update – Ilja Everilä Jun 15 '18 at 07:24
4 Answers
18
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)
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')
MySQL will suppress the error for duplicate primary key and gives a warning.

TrilceAC
- 301
- 3
- 10

shaktimaan
- 1,769
- 13
- 14
-
1Do you know what data does (values) receive? I’ve tried with a list of class instances (just like I would with add_all() but it doesn’t work... – lowercase00 Apr 09 '19 at 03:29
-
1Sorry for the late reply... `values()` takes in values to be inserted as arguments. Argument name should match tables columns. For e.g. `insert(customers).values(name=name, phone=phone,is_approved=is_approved)` And Table's structure is `Table ('customers', metadata, Column('name'), Column('phone'), Column('is_approved')` – shaktimaan Apr 13 '19 at 07:51
-
Thanks, I tried inserting the class’ instances but it ends up trying to insert the SQLAlchemy object itself, instead of the values. I chose to partially commit my code to the DB in order to avoid the eventual integrity error. I might try to drill down on the object and insert the values. – lowercase00 Apr 13 '19 at 09:11
10
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')

Bryan
- 184
- 1
- 4
1
Another method is:
stmt = YourModel.__table__.insert().prefix_with(" ignore").values(data)
session.execute(stmt)

buxizhizhoum
- 1,719
- 1
- 23
- 32
0
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)

codelover
- 44
- 3