Python MySQL不对查询参数的代理进行编码

Python MySQL doesn't encode surrogates for query parameters

提问人:TechnoSwiss 提问时间:7/29/2023 更新时间:7/29/2023 访问量:44

问:

运行尝试了 Python3.7 和 Python3.8,以及 mysql-connector-python 8.0.13 和 8.1.0

MySQL的5.7.42

数据库上的排序规则设置为“utf8mb4_unicode_520_ci”

来自 Python 的连接是:

db =  None
db = mysql.connector.connect(
    host="localhost",
    user=username,
    passwd=password,
    database=eventdb,
    charset="utf8mb4",
    use_unicode=True
)

cur = None
cur = db.cursor(dictionary=True)

我有一个来自 json.dump 的字符串,并尝试使用它运行参数化查询:

data["name"] = '\udced\udca0\udcbe\udced\udcb7\udca1\n\n\udced\udca0\udcbe\udced\udcb7\udca1\n\n♡ADANA♡♡EOMON♡'

sql = "SELECT db_name_id FROM db_name WHERE name = %s"
val = (data["name"],)
curr.execute(sql_text, sql_val)

mysql-connector-python 8.0.13 在两个版本的 Python 上都返回UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-5: surrogates not allowed

Python.38 上的 mysql-connector-python 8.1.0 返回_mysql_connector.MySQLInterfaceError: Failed converting Python 'str'

但是,如果我执行一个简单的查询:

cur.execute(SELECT db_name_id FROM db_name WHERE name = '\udced\udca0\udcbe\udced\udcb7\udca1\n\n\udced\udca0\udcbe\udced\udcb7\udca1\n\n♡ADANA♡♡EOMON♡')

然后它执行没有错误,这是一个用户输入的字段,我真的不想在没有参数的情况下进行查询。

复制我看到的异常错误的最简单示例是直接使用 C 扩展:

import _mysql_connector

ccnx = _mysql_connector.MySQL()
ccnx.connect(
                host="localhost",
                user="user",
                password="password",
                database="database"
            )

bad_str = 'just_an_��_example'

try:
    str_converted = ccnx.convert_to_mysql(*[bad_str])
    print('str converted is %s', str_converted)
except Exception as e:
    print('cant convert bad str %s',bad_str)
    print(e)

我只用 mysql-connector-python 8.1.0 测试过。

如果我根据信息 MySQL Bug 99757 进行以下更改,则convert_to_mysql有效:

import _mysql_connector

ccnx = _mysql_connector.MySQL()
ccnx.connect(
                host="localhost",
                user="user",
                password="password",
                database="database"
            )
ccnx.set_character_set('utf8')
bad_str = 'just_an_��_example'

try:
    str_converted = ccnx.convert_to_mysql(*[bad_str])
    print('str converted is %s', str_converted)
except Exception as e:
    print('cant convert bad str %s',bad_str)
    print(e)

在某些情况下,似乎对 mysql 字符串的转换被破坏了,包括带有代理项的参数化字符串。我希望我错过了一些东西。

Python MySQL 编码 UTF-8 代理项对

评论

0赞 Rick James 7/30/2023
这些代码看起来像叙利亚字母 ( րցւփքօֆևֈˉ֊֋֌֍ ֐ֱִַָֹֻּ֑֖֛֢֣֤֥֦֧֪֚֭֮֒֓֕֗֘֙֜֝֞֟֠֡֨֫֬֯־ְֲֳֵֶֺֽʿ ) -- 这是你所期待的吗?我没有看到MySQL或Unicode的问题,也许是Python?我看到 DCA0 1824=x0720 [ʠ] AL SYRIAC LETTER LAMADH DCA1 1825=x0721 [ʡ] AL SYRIAC LETTER MIM DCB7 1847=x0737 [ʷ] NSM SYRIAC RBASA BELOW DCBE 1854=x073E [ʾ] NSM SYRIAC ESASA BELOWDCxx
0赞 Rick James 7/30/2023
应该做什么?也就是说,为什么需要进行任何类型的转换?convert_to_mysql
0赞 JosefZ 7/30/2023
这些代码都是低代孕,没有任何意义。请编辑您的问题以改进您的最小可重复示例。特别是,分享那个奇怪的字符串的来源。请分享代码片段和数据样本(如有必要,请进行清理)。\uDCxx
0赞 TechnoSwiss 7/30/2023
convert_to_mysql我相信是mysql-connector用来编码字符串以进入mysql的函数。我实际上不确定,它恰好是一个最小的代码示例,我相信它表明 mysql-connector 中存在潜在的错误以及它如何处理代理项对。
0赞 TechnoSwiss 7/30/2023
这些是用户为在线 MMORPG 游戏输入的玩家名称,我正在解析游戏中的数据,无法控制用户输入的内容或游戏如何清理数据。所以我不确定这些角色实际上应该是什么。

答: 暂无答案