SQLAlchemy 报告 BINARY 列的“无效的 utf8mb4 字符串”

Pol*_*Pol 2 sqlalchemy mysql-python

假设这个 MySQL 表架构:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uuid` binary(16) NOT NULL,
  `email` varchar(255) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `photo` binary(16) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uuid` (`uuid`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
Run Code Online (Sandbox Code Playgroud)

当我使用execute()来自 SQLAlchemy 连接类的API 时:

with self.engine.begin() as connection:
  user_uuid = uuid.UUID("...")
  result = connection.execute("SELECT email, name, photo FROM user WHERE uuid=%s", user_uuid.bytes)
Run Code Online (Sandbox Code Playgroud)

如果 UUID 是F393A167-A919-4B50-BBB7-4AD356E89E6B,则 SQLAlchemy 会打印此警告:

/site-packages/sqlalchemy/engine/default.py:450: 警告:utf8mb4 字符串无效:'F393A1'

uuid列是一BINARY列,那么为什么 SQLAlchemy 将此参数视为文本参数而不是二进制参数,以及如何防止这种情况发生?

Pol*_*Pol 5

解释和解决方案实际上在 MySQL中的这个错误报告中

代替:

cursor.execute(""" INSERT INTO user(uuid) VALUES (%s) """, my_uuid)

cursor.execute(""" INSERT INTO user(uuid) VALUES (_binary %s) """, my_uuid)

注意下划线。它是“_binary”,而不是“binary”。这个“_binary”告诉 MySQL 下面的字符串将被解释为二进制,而不是被解释/验证为 utf8。