在SqlAlchemy中以数据库无关的方式指定列为UTF-8?
我发现我的MySQL数据库默认不是设置为UTF-8,而是选择了latin1_swedish_ci
这种字符排序方式。
因此,我遇到了一个用户报告的bug,说明我的应用程序不支持特殊字符。我检查了一下,确保我的应用程序能够正确处理UTF-8,写了一个测试,结果在内存中的SQLite上运行得很好,但在生产环境的MySQL上却不行。从SQLAlchemy的文档中,我似乎找到了一个解决方案,就是在我的列上指定一个字符排序方式:
column = db.Column(db.String(500, collation='utf8_general_ci'))
可惜的是,这导致我基于SQLite的单元测试失败——因为utf8_general_ci并不是SQLite支持的编码方式。这是MySQL特有的。
SQLite似乎在不指定字符排序的情况下也能很好地支持UTF-8。我可以用MySQL进行测试,但在内存中的SQLite数据库是一个更快、更简单的测试选项,适合快速测试。我非常重视测试的便利性,所以回到使用SQLite进行测试对我来说非常重要。
我尝试过的其他方法
我还尝试在我的连接字符串中添加
charset=utf8&use_unicode=1
我也用db.Unicode
代替了db.String
,但似乎没有什么区别。
问题
有没有一种简单且不依赖于数据库的方式,通过SQLAlchemy来指明某一列应该使用UTF-8编码?
1 个回答
2
我解决问题的方法是通过 __table_args__
来修改表的排序规则:
class Foo(Base):
__tablename__ = "foo"
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
...
column = db.Column(db.String(500))
SQLite 对这个 MySQL 的设置毫不在意,而 MySQL 则能正确识别这个设置。