Jen*_*ens 7 mysql blob sqlalchemy utf-8 python-3.x
我正在使用SQLAlchemy和MySQL,带有一个files表来存储文件.该表定义如下:
mysql> show full columns in files;
+---------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+---------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| id | varchar(32) | utf8_general_ci | NO | PRI | NULL | | select,insert,update,references | |
| created | datetime | NULL | YES | | NULL | | select,insert,update,references | |
| updated | datetime | NULL | YES | | NULL | | select,insert,update,references | |
| content | mediumblob | NULL | YES | | NULL | | select,insert,update,references | |
| name | varchar(500) | utf8_general_ci | YES | | NULL | | select,insert,update,references | |
+---------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
Run Code Online (Sandbox Code Playgroud)
类型的内容列MEDIUMBLOB是存储文件的位置.在SQLAlchemy中,该列声明为:
__maxsize__ = 12582912 # 12MiB
content = Column(LargeBinary(length=__maxsize__))
Run Code Online (Sandbox Code Playgroud)
我不太确定SQLAlchemy的BINARY类型和LargeBinary类型之间的区别.或者MySQL的VARBINARY类型和BLOB类型之间的区别.而且我不太确定这是否重要.
问题:每当我在该表中存储一个实际的二进制文件,即Python bytes或b''对象时,我会得到以下警告
.../python3.4/site-packages/sqlalchemy/engine/default.py:451: Warning: Invalid utf8 character string: 'BCB121'
cursor.execute(statement, parameters)
Run Code Online (Sandbox Code Playgroud)
我不想只是忽略警告,但似乎文件是完整的.如何优雅地处理此警告,如何解决其原因?
事实证明这是一个驱动程序问题。显然,默认的 MySQL 驱动程序在 Py3 和 utf8 支持方面遇到了问题。将cymysql安装到虚拟 Python 环境中解决了这个问题,并且警告消失了。
修复方法:查明 MySQL 是否通过套接字或端口连接(请参阅此处),然后相应地修改连接字符串。就我而言,使用套接字连接:
mysql+cymysql://user:pwd@localhost/database?unix_socket=/var/run/mysqld/mysqld.sock
Run Code Online (Sandbox Code Playgroud)
否则使用该port参数。
编辑:虽然上面解决了编码问题,但它引起了另一个问题:blob 大小。由于CyMySQL 中的错误,大于 8M 的 blob 无法提交。切换到PyMySQL解决了这个问题,尽管它对于大 blob似乎也有类似的问题。