sea-orm icon indicating copy to clipboard operation
sea-orm copied to clipboard

On conflict do nothing for MySQL

Open tp971 opened this issue 2 years ago • 2 comments

Description

OnConflict::do_nothing() generates a syntactically incorrect query for MySQL/MariaDB:

something::Entity::insert(...)
    .on_conflict(OnConflict::new()
        .do_nothing()
        .to_owned()
    )
    .build(DbBackend::MySql)

returns something like:

INSERT INTO `something` (...) VALUES (...) ON DUPLICATE KEY DO NOTHING

which is not correct in MySQL/MariaDB. The correct syntax would be:

INSERT IGNORE INTO `something` (...) VALUES (...)

(cf. https://dev.mysql.com/doc/refman/8.1/en/insert.html and https://mariadb.com/kb/en/insert/)

Workarounds

Update the unique key on conflict:

something::Entity::insert(...)
    .on_conflict(OnConflict::new()
        .update_column(something::Column::Id)
        .to_owned()
    )
    .build(DbBackend::MySql)

Versions

0.12.1

tp971 avatar Jul 29 '23 16:07 tp971

I don't think INSERT IGNORE should be used, as semantically it is different from ON DUPLICATE KEY. So ON DUPLICATE KEY UPDATE id=id is the way to go indeed.

Since SeaORM do know the PK of the entities, we are looking for ways to make it transparent.

tyt2y3 avatar Aug 22 '23 10:08 tyt2y3

Now it's released in sea-query 0.31.0-rc.5, this can now be implemented in SeaORM

tyt2y3 avatar Apr 14 '24 21:04 tyt2y3