MySQL 连接器 Python 变量未注册

MySQL connector Python variables not registering

我目前正在使用 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 变量。当我正确使用它时,比如在执行 'query' 或 'stmt' 时,它不起作用。通常我会收到一条错误消息

" You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''p1' = 1 WHERE id = 21'".

但是,如果我这样做:

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

它按预期正常工作。

编辑:我检查了我的后端,显然 UPDATE 语句实际上并没有更新任何东西。所以现在我完全不知所措了。

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

我的 table 架构 '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    |       |
+-------+---------+------+-----+---------+-------+

那是因为当 MySQL 连接器将您的变量注入 SQL 语句时,它会根据它们的类型对其进行格式化。

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

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

所以您的 SQL 查询可能如下所示:

SELECT 'p1' FROM cartdata WHERE id = someId

语法无效SQL...

不过,您的第二个选择似乎还不错。顺便说一句,根据用户的输入调整您想要 select 的列似乎很奇怪......我强烈建议用一些有效的东西来验证这个值......


详情

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

同上:

SET %s = ...

生成:

SET 'colName' = ...

这是无效的,因为您正试图将一个值影响到另一个值...

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

'foo' = 'bar'

'foo' = 4

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

同上:

WHERE colName = %s

生成:

WHERE colName = 'fooBar'

这是有效的,因为您筛选等于字符串 fooBar.

的值

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

SELECT %s FROM cartdata WHERE id = %s

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