我一直在为此奋斗几个小时,我现在感到哭泣,因为我无法理解正在发生的事情。
以下是我的数据的简化版本:
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数据库的问题,而是我如何将变量传递到数据库中。
我还有一个问题是如何将值作为浮点数插入?目前我在表格中将值定义为 TINYTEXT NOT NULL ,我希望这是 FLOAT NOT NULL 但是我我不知道如何处理上面的替代品。
答案 0 :(得分:4)
无需使用生成器循环mydata
。只需直接传递mydata
:
cur.executemany(sql, mydata)
数据库适配器将为您循环mydata
,生成器表达式只会插入一个不必要的额外循环。
如果您没有收到任何错误消息,但也没有任何更改,请检查以下内容:
确保您提交交易; con.commit()
致电后运行.executemany()
。
Tripple-check mydata
不为空。
数据库适配器将为您正确处理浮点值;如果一列被标记为FLOAT NOT NULL
并且您传入了该列的Python浮点值,那么就行了。这就是SQL参数的用途,正确处理不同数据类型的引用。
答案 1 :(得分:1)
默认情况下,在MYSQL中启用自动提交。要检查设置中的当前配置,请连接到MYSQL实例并执行以下操作。
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
如果值为1,则启用...否则不......
说实话,你的原始代码段对我来说很好。所以这可能主要是一个自动提交问题。
尝试在原始代码中con.close()
之前添加以下行。
con.commit()
如果启用了自动提交,您仍然可以尝试使用下面发布的代码段...您是否可以将mydata列表成员从Dictionary更改为Tuple类型?如果是,那么请查看以下代码段是否对您有所帮助。
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()
答案 2 :(得分:0)
只是一个扩展Guddu的FYI,您可以通过执行以下操作将字典转换为元组类型:
mydata_modified = []
for x in mydata:
mydata_modified.append(tuple(x.values()))