在python MySQLdb的executemany()中包含数据库函数调用
当我尝试运行像这样的语句时:
cursor.executemany("""INSERT INTO `test` (`id`,`data`,`time_added`)
VALUES (%s, %s, NOW())""", [(i.id, i.data) for i in items])
MySQLdb 在处理 NOW() 里的右括号时出现问题,因为它把这个括号当成了值块的结束。这意味着,查询看起来像这样:
('1', 'a', NOW(), ('2','b', NOW(), ('3','c',NOW())
而 MYSQL 报告了一个语法错误。实际上,它们应该看起来像这样:
('1', 'a', NOW()), ('2','b', NOW()), ('3','c',NOW())
应该有某种方法可以处理 NOW(),但我不知道怎么做。把 'NOW()' 加入到元组里不行,因为这样 NOW() 就被引起来了,数据库把它当成字符串,而不是函数调用。
通过使用当前时间戳作为默认值来解决这个问题也不行——这只是一个例子,我需要用各种数据库函数来做这种事情,而不仅仅是 NOW()。
谢谢!
1 个回答
1
下面这个方法并不是最理想的,但不幸的是,这是我知道的唯一方法。
这个想法是手动构建SQL语句,使用 connection.literal
来帮你处理参数的转义:
cursor=connection.cursor()
args=[(1,'foo'),(2,'bar')]
sql=('INSERT INTO `foo` (`fooid`,`data`,`time_added`) VALUES '
+','.join(
['(%s,%s,NOW())'%connection.literal(arg)
for arg in args]))
cursor.execute(sql)
这看起来很糟糕,可能让你觉得不舒服,但如果你深入了解(在 /usr/lib/pymodules/python2.6/MySQLdb/cursors.py 文件中)MySQLdb 在 cursors.executemany
中做了什么,我觉得这和那个函数的做法差不多,只是因为正则表达式 cursors.insert_values
没有正确解析嵌套的括号而导致了一些混乱。(哎呀!)
我刚刚 安装了 oursql,这是 MySQLdb 的一个替代品,很高兴地报告说
sql='INSERT INTO `foo` (`fooid`,`data`,`time_added`) VALUES (?,?,NOW())'
cursor.executemany(sql,args)
在使用 oursql 时,效果如预期。