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

时间:2014-12-25 18:36:27

标签: 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

发生了什么?

3 个答案:

答案 0 :(得分: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/Python以及prepare=True工厂中的显式.cursor()选项 - 请参阅http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html。这使得您可以使用特定的游标来准备哪些语句(根据mysql.com页面,“比使用PREPARE和EXECUTE”二进制协议更有效),另一个用于更好未准备的语句; “明确比隐含更好”在“禅宗的Python”中的所有原则之后(import this从交互式提示阅读所有这些原则)。 mysqldb隐式地做事(似乎当前的开源版本使用预准备语句)不能像Connector/Python更明确的架构一样好之一。

答案 1 :(得分: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

答案 2 :(得分: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()

选择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