我试图在Python中使用带有预处理语句的SQL.Python没有自己的机制,所以我尝试直接使用SQL:
sql = "PREPARE stmt FROM ' INSERT INTO {} (date, time, tag, power) VALUES (?, ?, ?, ?)'".format(self.db_scan_table)
self.cursor.execute(sql)
Run Code Online (Sandbox Code Playgroud)
然后,在循环中:
sql = "EXECUTE stmt USING \'{}\', \'{}\', {}, {};".format(d, t, tag, power)
self.cursor.execute(sql)
Run Code Online (Sandbox Code Playgroud)
在循环中,我得到:
MySQL Error [1064]: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2014-12-25', '12:31:46', 88000000, -6.64' at line 1
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
在Python中使用MySQL中的预准备语句可以在http://zetcode.com/db/mysqlpython/中找到 - 在该页面中查找Prepared statements.
在你的情况下,那将是,例如:
sql = ('INSERT INTO {} (date, time, tag, power) VALUES '
'(%s, %s, %s, %s)'.format(self.db_scan_table))
Run Code Online (Sandbox Code Playgroud)
然后,就像你说的那样"在循环中":
self.cursor.execute(sql, (d, t, tag, power))
Run Code Online (Sandbox Code Playgroud)
没有进一步的字符串格式化 - MySQLdb模块代表您执行准备和执行部分(并且可以缓存事物以避免不必要地重复工作等等).
根据你提到的"循环"的性质,你应该考虑单个调用.execute_many(使用一系列元组作为第二个参数)可以取代整个循环(除非你需要更多的处理)循环不仅仅是将数据插入数据库).
补充:现在更好的替代方案可能是在工厂中使用mysql自己的Connector/Python和显式prepare=True选项.cursor()- 请参阅http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html.这使得您可以使用特定的游标来准备哪些语句(根据mysql.com页面,"比使用PREPARE和EXECUTE"二进制协议更有效),另一个用于更好未准备的语句; "明确胜过隐性" 是 "禅宗之谜"中的一条原则(import this从交互式提示中读取所有这些原则). mysqldb隐式地做事(似乎当前的开源版本不使用预处理语句)不能像一个Connector/Python更明确的架构那么好.
| 归档时间: |
|
| 查看次数: |
26207 次 |
| 最近记录: |