今天写的一个小功能,里面要用MySQLdb更新数据库,语句如下
sql = "update %s.account_operation set status=1 where username=‘%s‘" % (allResDBInfos[‘db‘], username)
变量替换后,是下面的样子
update suspects.account_operation set status=1 where username=‘[email protected]‘
语句没问题,数据库中也存在username为‘[email protected]‘的记录,并且手动执行也是正确的(status被正确的更新为1)
但奇怪的就是在Python中用MySQLdb更新的时候没有效果
原因就是suspects.account_operation这张表用的InnoDB引擎,InnoDB是事务性引擎,有个autocommit的变量控制是否自动提交事务。InnoDB默认的autocommit=1,也就是说,每条语句都是一个事务,都会被自动提交。但如果设置autocommit=0,关闭自动提交的话,就需要我们手动commit了。commit之前的所有更新都在一个事务内,如果不commit的话,这些更新都不会生效。
用MySQL的客户端连接时,autocommit=1,是会自动提交的。有意思的是,MySQLdb这个库默认autocommit=0,所以需要手动提交。
下面是MySQLdb的关于autocommit的说明,从1.2.0版本开始,默认禁用autocommit。
链接:http://mysql-python.sourceforge.net/FAQ.html#my-data-disappeared-or-won-t-go-away
My data disappeared! (or won‘t go away!)
Starting with 1.2.0, MySQLdb disables autocommit by default, as required by the DB-API standard (PEP-249). If you are using InnoDB tables or some other type of transactional table type, you‘ll need to do connection.commit() before closing the connection, or else none of your changes will be written to the database.
Conversely, you can also use connection.rollback() to throw away any changes you‘ve made since the last commit.
Important note: Some SQL statements -- specifically DDL statements like CREATE TABLE -- are non-transactional, so they can‘t be rolled back, and they cause pending transactions to commit.
上面这些内容都是针对InnoDB的,对于MyISAM这样的非事务性引擎,不存在事务概念,只管更新即可,autocommit是0或1都没有影响。