PyMysql UPDATE query

31,599

Solution 1

When you execute your update, MySQL is implicitly starting a transaction. You need to commit this transaction by calling connection.commit() after you execute your update to keep the transaction from automatically rolling back when you disconnect.

MySQL (at least when using the InnoDB engine for tables) supports transactions, which allow you to run a series of update/insert statements then have them either all commit at once effectively as a single operation, or rollback so that none are applied. If you do not explicitly commit a transaction, it will rollback automatically when you close your connection to the database.

Solution 2

In fact, what @JoeDay has described above has little to do with default MySQL transaction's behaviour. MySQL by default operates in auto-commit mode and normally you don't need any additional twist to persist your changes:

By default, MySQL runs with autocommit mode enabled. This means that as soon as you execute a statement that updates (modifies) a table, MySQL stores the update on disk to make it permanent. The change cannot be rolled back.

PEP-249's (DB API) authors decided to complicate things and break Zen of Python by making a transaction's start implicit, by proposing auto-commit to be disabled by default.

What I suggest to do, is to restore MySQL's default behaviour. And use transactions explicitly, only when you need them.

import pymysql

connection = pymysql.connect(autocommit=True)

I've also written about it here with a few references.

Share:
31,599
Shay
Author by

Shay

Updated on February 25, 2020

Comments

  • Shay
    Shay about 4 years

    I've been trying using PyMysql and so far everything i did worked (Select/insert) but when i try to update it just doesn't work, no errors no nothing, just doesn't do anything.

    import pymysql
    connection = pymysql.connect(...)
    cursor = connection.cursor()
    cursor.execute("UPDATE Users SET IsConnected='1' WHERE Username='test'")
    cursor.close()
    connection.close()
    

    and yes I've double checked that Users, IsConnected and Username are all correct and test does exist (SELECT works on it)

    what's my problem here?

    • Joe Day
      Joe Day almost 11 years
      I suspect pymysql is automatically starting a transaction which you are not explicitly committing, so its rolling back when you close the connection.
    • Shay
      Shay almost 11 years
      So what should i do to fix it? remove the cursor.close() connection.close()?
    • Joe Day
      Joe Day almost 11 years
      try a call to connection.commit() after your call to cursor.execute()
    • Shay
      Shay almost 11 years
      It worked! but can you try to explain to me what .commit() exactly does so I can understand what went wrong?
  • radtek
    radtek over 6 years
    This is the best answer!
  • ZuOverture
    ZuOverture about 6 years
    Turning on autocommit can significantly decrease the performance of transactions. Not in the author's simple case, though.
  • saaj
    saaj about 6 years
    @ZuOverture Autocommit has nothing to do with performance of transactions as such. You, as a developer, control granularity and isolation of transactions which directly affects their performance.
  • ZuOverture
    ZuOverture about 6 years
    @saaj, I wasn't talking about performance of their intrinsics, obviously. Autocommit is not off by default in pymysql for no reason, it encourages learning how to organize transactions to avoid excessive autocommit overhead.
  • Nicolay77
    Nicolay77 over 4 years
    The answer as always is: it depends. Explicit commits are needed in Oracle and they change performance in a very noticeable way. In MySQL the difference is negligible and they just over complicate things. In case of doubt, always measure!