使用Python和MySQLdb将多个字典对象插入MySQL数据库

2 投票
4 回答
12782 浏览
提问于 2025-04-17 14:58

我已经为这个问题挣扎了好几个小时,现在感觉快要哭了,因为我实在搞不懂发生了什么。

这是我数据的一个简化版本:

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插入为浮点数?目前我在表中定义valueTINYTEXT NOT NULL,我想把它改为FLOAT NOT NULL,但我不太确定该怎么处理这个替换。

4 个回答

0

只是想补充一下,关于Guddu的内容,你可以通过以下方式把字典转换成元组类型:

mydata_modified = []
for x in mydata:
   mydata_modified.append(tuple(x.values()))
2

在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()
6

其实你不需要用生成器来遍历 mydata,直接把 mydata 传进去就可以了:

cur.executemany(sql, mydata)

数据库适配器会帮你遍历 mydata,而使用生成器表达式只会多加一个不必要的循环。

如果你没有收到错误信息,但也没有任何变化,可以检查以下几点:

  • 确保你提交了事务;在 .executemany() 调用之后,运行 con.commit()

  • 仔细检查 mydata 是否为空。

数据库适配器会正确处理浮点值;如果某一列标记为 FLOAT NOT NULL,而你传入一个 Python 的浮点值,事情就会正常运作。这就是 SQL 参数的作用,能够正确处理不同数据类型的引号问题。

撰写回答