在python中使用带有mysql的预处理语句

我试图在Python中使用带有预处理语句的SQL。 Python没有自己的机制,所以我尝试直接使用SQL:

sql = "PREPARE stmt FROM ' INSERT INTO {} (date, time, tag, power) VALUES (?, ?, ?, ?)'".format(self.db_scan_table)
self.cursor.execute(sql)

然后,在循环中:

sql = "EXECUTE stmt USING \'{}\', \'{}\', {}, {};".format(d, t, tag, power)
self.cursor.execute(sql)

在循环中,我得到:

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

这是怎么回事?

7
投票

在http://zetcode.com/db/mysqlpython/中解释了在Python中使用MySQL编写的语句 - 在Prepared statements的页面中查看。

在你的情况下,那将是,例如:

sql = ('INSERT INTO {} (date, time, tag, power) VALUES '
       '(%s, %s, %s, %s)'.format(self.db_scan_table))

然后,就像你说的那样“在循环中”:

self.cursor.execute(sql, (d, t, tag, power))

没有进一步的字符串格式化 - MySQLdb模块代表您做准备和执行部分(并且可以缓存事物以避免不必要地重复工作等)。

根据你提到的“循环”的性质,考虑一下对.execute_many(以一系列元组作为第二个参数)的单个调用可能取代整个循环(除非你需要更多的处理)这种循环不仅仅是将数据插入数据库中。

补充:现在更好的替代方案可能是使用mysql自己的Connector/Pythonprepare=True工厂中的显式.cursor()选项 - 请参阅http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html。这使得您可以使用特定的游标来准备哪些语句(根据mysql.com页面,“比使用PREPARE和EXECUTE”二进制协议更有效),另一个用于更好未准备的语句; “明确胜过隐性”是“禅宗之谜”中的一个原则(import this来自互动提示,阅读所有这些原则)。 mysqldb隐含地做事(而且似乎当前的开源版本不使用预处理语句)不能像Connector/Python那样更加明确的架构。

2
投票

Python确实支持预处理语句:

sql = "INSERT INTO {} (date, time, tag, power) VALUES (%s, %s, %s, %s);"
sql = sql.format(self.db_scan_table)
self.cursor.execute(sql, (d, t, tag, power))

(你应该确保self.db_scan_table不容易受到SQL注入攻击)

这假设你的paramstyle'format',它should be for MySQL。

0
投票
        import mysql.connector
        db_con=mysql.connector.connect(host='',
            database='',
            user='',
            password='')

        cursor = db_con.cursor(prepared=True,)
        #cursor = db_con.cursor(prepared=True)#IT MAY HAVE PROBLEM

        sql = """INSERT INTO table (xy,zy) VALUES (%s, %s)"""
        input=(1,2)
        cursor.execute(sql , input)
        db_con.commit()

SELECT STMT

        sql = """SELECT * FROM TABLE WHERE XY=%s ORDER BY id DESC LIMIT 1 """
        ID=1

        input=(ID,)
        #input=(ID)# IT MAY HAS PROBLEM
        cursor.execute(sql, input)
        data = cursor.fetchall()
        rowsNumber=cursor.rowcount