【发布时间】:2020-04-06 19:05:11
【问题描述】:
我正在使用带有 mysqlclient 的 MySql 和 Python 3.6/3.8 来维护具有二进制字段的数据库。该代码是在我使用 Python 2.7 之前构建的,用于直接插入包含二进制数据的字段。例如,表格看起来像
+-------------------------+--------------------------------------------------------------------+------+-----+------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------+--------------------------------------------------------------------+------+-----+------------+-------+
| license_id | varchar(36) | NO | PRI | NULL | |
| data | binary(32) | NO | UNI | NULL | |
+-------------------------+--------------------------------------------------------------------+------+-----+------------+-------+
插入命令看起来像:
dbconn.execute("""INSERT into datatable (
license_id,
data)
VALUES ("{:s}", "{:s}")
""".format(
str(self._license_id),
escape_string(self._data)))
这将导致 Python 2.7 直接在命令中插入二进制数据,例如
INSERT into datatable (license_id, data) VALUES ("XXX-XXX-52", "������C�...\r�x�b24�B")
但在 Python 3 中,数据是字节数组类型,不能插入到字符串中,尝试对其进行解码会导致:
escape_string(self._auth_hash).decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 5: invalid continuation byte
其他问题似乎表明解决此问题的可行途径是将二进制转换为十六进制(例如here),但是有没有办法像原始代码一样插入到 Python 3 unicode 字符串中而不会出错?
删除"{:s}" 周围的引号并使用binascii.b2a_hex(self._data) 会出现相同的意图,但尚不清楚这将具有完全相同的行为或是否会出现问题。我预计这是一个反复出现的问题,并且正在寻找副作用最小的解决方案。
【问题讨论】:
标签: python mysql sql python-3.x python-2.7