Search code examples
pythonmysqlsql-insertpymysqldatabase-cursor

Mysql rowcount always returns 1 on INSERT IGNORE statement


I am using pymysql connector to do some inserts into my database. I am trying to return whether or not a record was added or updated.

My code is

import pymysql
db = pymysql.connect(host='127.0.0.1',user='USERNAME',password='PASSWORD',database='DATABASE')
cursor = db.cursor()

sql = "INSERT IGNORE INTO `Table` (key, via) SELECT temp.`id`, 'Via_Bot' FROM (SELECT %s AS id) temp LEFT JOIN `Other_Table` ON `Other_Table`.id = temp.id WHERE `Other_Table`.id IS NULL;"
key_id = 'ab12cd'
rows = cursor.execute(sql, (key_id,))

db.commit()

In this situation rows and cursor.rowcount always returns 1 even if a record was not inserted/modified. How do I correctly see if a record has been updated/inserted?


Solution

  • The issue here is that INSERT IGNORE does not provide a way to differentiate between a successful insert and an ignored operation. The cursor.execute() method will return 1 because the statement itself was executed successfully, regardless of whether a row was inserted or ignored.

    Instead of INSERT IGNORE, you can use INSERT ... ON DUPLICATE KEY UPDATE and check cursor.rowcount

    import pymysql
    
    db = pymysql.connect(host='127.0.0.1', user='USERNAME', password='PASSWORD', database='DATABASE')
    cursor = db.cursor()
    
    sql = """
    INSERT INTO `Table` (key, via)
    VALUES (%s, 'Via_Bot')
    ON DUPLICATE KEY UPDATE via = VALUES(via);
    """
    
    key_id = 'ab12cd'
    rows = cursor.execute(sql, (key_id,))
    
    db.commit()
    
    if rows == 1:
        print("Record inserted.")
    elif rows == 2:
        print("Record updated.")
    else:
        print("No changes made.")