如何在Alembic迁移中指定编码解决UnicodeDecodeError报错
问题原因
这个报错发生在Python层的字符串类型转换阶段,还未到和PostgreSQL数据库交互的环节,和Alembic、Psycopg2的默认编码配置无关,本质是Python 2的字符串规则导致的:
- Python 2中不带
u前缀的字符串默认是str类型的字节串,你写入的Unicode字符会被默认用源码编码(如果没指定源码编码默认是ASCII)转成字节存储 - SQLAlchemy内部执行语句前会调用
util.text_type()将输入语句转成unicode类型,这个转换默认用ASCII编码解码字节串,遇到超出ASCII范围的字符就触发报错
你之前配置引擎的encoding='utf-8'参数不生效,是因为该参数仅控制SQLAlchemy和数据库交互时的编码转换规则,不影响Python层的字符串隐式转换逻辑。
解决方案
方案1:直接给SQL字符串加u前缀(推荐,单迁移修改无副作用)
直接声明你传入的是Unicode类型字符串,跳过隐式解码步骤:
def upgrade(): op.execute(u"SELECT '𝔥𝔢𝔩𝔩𝔬'")
如果SQL内容是从外部文件读取的,手动用UTF-8解码成Unicode类型再传入:
def upgrade(): with open("your_sql_file.sql", "rb") as f: sql_str = f.read().decode("utf-8") op.execute(sql_str)
方案2:全局修改Python 2默认编码(适合批量迁移场景)
在Alembic的env.py文件最开头加入以下代码,全局修改Python 2的默认隐式解码编码为UTF-8,所有迁移都无需再单独调整字符串:
import sys # 重载sys模块才能调用setdefaultencoding,Python 2专属 reload(sys) sys.setdefaultencoding('utf-8')
该修改仅在Alembic迁移的运行环境内生效,不会影响你的项目业务代码。
内容的提问来源于stack exchange,提问作者Stew
相关产品推荐
相关产品推荐

