使用Python和MySQLdb将多个字典对象插入MySQL数据库
我已经为这个问题挣扎了好几个小时,现在感觉快要哭了,因为我实在搞不懂发生了什么。
这是我数据的一个简化版本:
mydata = [ { 'id': 123, 'thing': 'ghi', 'value': 1 }, { 'id': 456, 'thing': 'xyz', 'value': 0 } ]
这是我写的代码:
import MySQLdb as mdb
con = None
con = mdb.connect('localhost', 'testing', 'anothervalue', 'andanother');
cur = con.cursor()
sql = "INSERT INTO `tablename` ( `id`, `thing`, `value` ) VALUES ( %(id)s, %(thing)s, %(value)s )"
cur.executemany( sql, ( mine for mine in mydata ) )
con.close()
我原本期待的是能在tablename中插入2行数据。但实际上,脚本执行没有任何错误,却没有插入任何行。
我到底哪里做错了?如果我手动执行一次INSERT操作,它能正常插入到表中,所以我觉得问题不在MySQL数据库,而是在我把变量传递到数据库的方式上。
我还有一个额外的问题,就是如何把value插入为浮点数?目前我在表中定义value为TINYTEXT NOT NULL,我想把它改为FLOAT NOT NULL,但我不太确定该怎么处理这个替换。
4 个回答
只是想补充一下,关于Guddu的内容,你可以通过以下方式把字典转换成元组类型:
mydata_modified = []
for x in mydata:
mydata_modified.append(tuple(x.values()))
在MYSQL中,默认情况下是开启自动提交的。要检查你当前的设置,可以连接到你的MYSQL实例,然后执行以下命令。
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
如果返回的值是1,那就是开启了自动提交……否则就是没有开启。
老实说,你原来的代码对我来说运行得很好。所以这很可能是自动提交的问题。
试着在你原始代码中的con.close()
之前添加以下这一行。
con.commit()
如果自动提交是开启的,你也可以试试我下面提供的代码片段……你能把mydata列表中的成员从字典类型改成元组类型吗?如果可以的话,请看看以下代码片段是否对你有帮助。
import MySQLdb as mdb
mydata = [ { 'id': 123, 'thing': 'ghi', 'value': 1 }, { 'id': 456, 'thing': 'xyz', 'value': 0 } ]
mydata_modified=[ (123, 'ghi', 1 ), ( 456, 'xyz', 0 ) ]
con = None
con = mdb.connect('localhost', 'testing', 'anothervalue', 'andanother');
cur = con.cursor()
cur.executemany( """INSERT INTO tablename ( id, thing, value ) VALUES ( %s, %s, %s )""", mydata_modified )
con.commit()
con.close()
其实你不需要用生成器来遍历 mydata
,直接把 mydata
传进去就可以了:
cur.executemany(sql, mydata)
数据库适配器会帮你遍历 mydata
,而使用生成器表达式只会多加一个不必要的循环。
如果你没有收到错误信息,但也没有任何变化,可以检查以下几点:
确保你提交了事务;在
.executemany()
调用之后,运行con.commit()
。仔细检查
mydata
是否为空。
数据库适配器会正确处理浮点值;如果某一列标记为 FLOAT NOT NULL
,而你传入一个 Python 的浮点值,事情就会正常运作。这就是 SQL 参数的作用,能够正确处理不同数据类型的引号问题。