Fly.io部署Django+PostgreSQL时执行makemigrations遇Unicode解码错误求助
解决Django部署Fly.io时makemigrations的UnicodeDecodeError问题
核心问题分析
出现UnicodeDecodeError是因为你手动硬编码的DATABASE_URL包含了无法被UTF-8解码的字节,大概率是密码部分的特殊字符未正确处理,或是手动复制URL时引入了格式错误。另外,硬编码环境变量的做法也不符合Fly.io的部署规范。
解决方案
1. 移除settings.py中硬编码的DATABASE_URL
Fly.io执行flyctl pg attach后已经自动将正确的DATABASE_URL添加为应用secret,不需要手动在代码里设置os.environ['DATABASE_URL']。修改settings.py如下:
import os import dj_database_url # 删掉硬编码环境变量的行:os.environ['DATABASE_URL'] = 'postgres://ac7:<PASSWORD>@ac7-postgres.flycast:5432/ac7?sslmode=disable' DATABASES = { 'default': dj_database_url.config(default=os.getenv('DATABASE_URL')) }
2. 本地开发环境正确加载secret
如果需要本地测试,不要手动复制粘贴URL,按以下步骤操作:
- 执行
flyctl secrets list查看应用的secret,复制DATABASE_URL的完整值 - 创建
.env文件,将复制到的DATABASE_URL完整内容粘贴进去 - 安装依赖:
pip install python-dotenv - 在settings.py开头添加加载代码:
from dotenv import load_dotenv load_dotenv()
3. 手动构造URL时处理密码编码(可选)
如果必须手动构造数据库URL,密码中的特殊字符(如非ASCII字符、&、@、=等)需要进行URL编码,用Python内置工具处理:
from urllib.parse import quote_plus password = "你的原始密码" encoded_password = quote_plus(password) DATABASE_URL = f"postgres://ac7:{encoded_password}@ac7-postgres.flycast:5432/ac7?sslmode=disable"
验证步骤
- 本地环境:执行
py manage.py makemigrations,确认错误消失 - 部署环境:重新部署应用,Fly.io会自动加载secret中的
DATABASE_URL,无需额外配置
内容的提问来源于stack exchange,提问作者Matheus Marques
相关产品推荐
相关产品推荐

