MySQL连接器Python变量未注册

时间:2018-09-25 20:44:35

标签: python mysql mysql-connector-python

我目前正在使用mysql-connector-python包在Flask上执行数据库操作。一直运行得很好,直到突然之间变量似乎不再正常工作为止。我的代码在这里:

@bp.route('/addcart', methods=('OPTIONS', 'POST'))
def addcart():
        ...
        userID = session.get("user_id")
        reqDict = request.get_json()
        itemCode = str(reqDict['itemCode'])
        itemAmt = reqDict['itemAmt']

        if userID is not None:
            db = get_db()
            cursor = db.cursor()
            query = ('SELECT %s FROM cartdata WHERE id = %s')

            cursor.execute(query, (itemCode, userID))
            currentNum = cursor.fetchone()[0]

            if currentNum is None:
                stmt = ('UPDATE cartdata SET %s = 1 WHERE id = %s')
                cursor.execute(stmt, (itemCode, userID))
            else:
                currentNum = int(currentNum) + int(itemAmt)
                stmt = ('UPDATE cartdata SET %s = %s WHERE id = %s')
                cursor.execute(stmt, (itemCode, currentNum, userID))
            ....

由于某种原因,我似乎在itemCode变量上遇到了麻烦。当我正确使用它时,例如在执行“查询”或“ stmt”时,它不起作用。通常情况下,我会说

  

“您的SQL语法有误;请查看   对应于您的MySQL服务器版本以使用正确的语法   靠近“ p1” = 1 WHERE id = 21'”。

但是,如果我这样做:

query = ('SELECT ' + itemCode + ' FROM cartdata WHERE id = %s')
...
stmt = ('UPDATE cartdata SET '+ itemCode +' = 1 WHERE id = %s')
...

它可以按预期正常工作。

编辑:我已经检查了后端,并且显然UPDATE语句实际上并未更新任何内容。所以现在我完全不知所措。

我不明白为什么连接器现在突然因变量而中断。我已经检查了此变量及其类型,但是它们是预期的类型。任何见解都会有所帮助。

我的'cartdata'表结构如下所示:

+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI | NULL    |       |
| p1    | int(8)  | YES  |     | NULL    |       |
| p2    | int(8)  | YES  |     | NULL    |       |
| p3    | int(8)  | YES  |     | NULL    |       |
| p4    | int(8)  | YES  |     | NULL    |       |
| p5    | int(8)  | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

1 个答案:

答案 0 :(得分:1)

这是因为,当MySQL连接器将变量注入SQL语句时,它将根据其类型设置其格式。

您实际上可以在收到的错误消息中看到它:

"p1' = 1 WHERE id = 21'"
  ^

因此,您的SQL查询可能如下所示:

SELECT 'p1' FROM cartdata WHERE id = someId

哪个在语法上是无效的SQL ...

您的第二个选择似乎还可以。顺便说一句,根据用户的输入来调整要选择的列似乎很奇怪。我强烈建议您使用有效的方法来验证该值。


详细信息

您不能使用%s作为列名,因为这会在SQL查询中注入字符串值,并且会导致SQL语法无效(列名不是字符串值)。 / p>

如上所述:

SET %s = ...

生成:

SET 'colName' = ...

这无效,因为您正尝试将一个值影响为另一个值...

这与尝试在python中执行以下操作相同:

'foo' = 'bar'

'foo' = 4

设置值(使用%s)或过滤值(使用SET colName = %s)时,可以使用WHERE colName = %s,因为列colName中的值类型实际上是字符串。

如上所述:

WHERE colName = %s

生成:

WHERE colName = 'fooBar'

之所以有效,是因为您过滤了等于字符串fooBar的值。


顺便说一句,您可能想检查一下

SELECT %s FROM cartdata WHERE id = %s

因此给您。这可能会导致问题...实际上,MySQL不会告诉您任何信息,但您得到的结果可能恰好是itemCode的值。 (这是有效的SQL SELECT 'hello',只返回'hello')。