40

I'm having some trouble updating a row in a MySQL database. Here is the code I'm trying to run:

import MySQLdb

conn=MySQLdb.connect(host="localhost", user="root", passwd="pass", db="dbname")
cursor=conn.cursor()

cursor.execute("UPDATE compinfo SET Co_num=4 WHERE ID=100")
cursor.execute("SELECT Co_num FROM compinfo WHERE ID=100")
results = cursor.fetchall()

for row in results:
    print row[0]

print "Number of rows updated: %d" % cursor.rowcount

cursor.close()
conn.close()

The output I get when I run this program is:

4
Number of rows updated: 1

It seems like it's working but if I query the database from the MySQL command line interface (CLI) I find that it was not updated at all. However, if from the CLI I enter UPDATE compinfo SET Co_num=4 WHERE ID=100; the database is updated as expected.

What is my problem? I'm running Python 2.5.2 with MySQL 5.1.30 on a Windows box.

Air
  • 8,274
  • 2
  • 53
  • 88
Ian Burris
  • 6,325
  • 21
  • 59
  • 80

6 Answers6

67

I am not certain, but I am going to guess you are using a INNODB table, and you haven't done a commit. I believe MySQLdb enable transactions automatically.

Call conn.commit() before calling close.

From the FAQ: Starting with 1.2.0, MySQLdb disables autocommit by default

davidism
  • 121,510
  • 29
  • 395
  • 339
Zoredache
  • 37,543
  • 7
  • 45
  • 61
  • I find it handy cause you don't have to manage rollback manually if something goes wrong. In case you need multiple queries to update the database. – Sergei Aug 11 '16 at 21:34
31

MySQLdb has autocommit off by default, which may be confusing at first. Your connection exists in its own transaction and you will not be able to see the changes you make from other connections until you commit that transaction.

You can either do conn.commit() after the update statement as others have pointed out, or disable this functionality altogether by setting conn.autocommit(True) right after you create the connection object.

davidism
  • 121,510
  • 29
  • 395
  • 339
ʞɔıu
  • 47,148
  • 35
  • 106
  • 149
  • Setting conn.autocommit(true) after connecting means that it sends two superfluous commands to the server- it would be better if there was a way of avoiding them. – MarkR Dec 21 '08 at 14:54
  • it *would* be better if there were such a way, I agree. but it's not like it's an expensive statement. – ʞɔıu Dec 22 '08 at 00:30
  • Expensive is a matter of opinion... if your server is some distance away, you've still got two needless round-trips. – MarkR Dec 22 '08 at 07:47
  • I did an explicit conn.commit after a command, the rowcount said all was ok but looking at it outside of that app, it had failed. Setting it to autocommit did the trick. Don't know if this is a bug : but thanks ʞɔıu -- helped me a lot!! – David Hall Apr 05 '11 at 19:42
9

You need to commit changes manually or turn auto-commit on.

The reason SELECT returns the modified (but not persisted) data is because the connection is still in the same transaction.

muhuk
  • 15,777
  • 9
  • 59
  • 98
3

I've found that Python's connector automatically turns autocommit off, and there doesn't appear to be any way to change this behaviour. Of course you can turn it back on, but then looking at the query logs, it stupidly does two pointless queries after connect to turn autocommit off then back on.

MarkR
  • 62,604
  • 14
  • 116
  • 151
2

Connector/Python Connection Arguments

Turning on autocommit can be done directly when you connect to a database:

import mysql.connector as db
conn = db.connect(host="localhost", user="root", passwd="pass", db="dbname", autocommit=True)

MySQLConnection.autocommit Property

Or separately:

import MySQLdb

conn = MySQLdb.connect(host="localhost", user="root", passwd="pass", db="dbname")
cursor = conn.cursor()
conn.get_autocommit()        # will return **False**
conn.autocommit(True)        # will make it True
conn.get_autocommit()        # Should return **True** now
cursor = conn.cursor()

Explicitly committing the changes is done with

conn.commit()
urek mazino
  • 130
  • 12
Milovan Tomašević
  • 6,823
  • 1
  • 50
  • 42
0

I have to execute SET autocommit=true on my mysqlWorkbench app script

Youth overturn
  • 341
  • 5
  • 7