Django部署Heroku后上传CSV报PostgreSQL字符超长错误如何解决?
问题根因说明
- 本地开发如果使用SQLite数据库,SQLite本身不强制校验
varchar类型的长度限制,即使字段值超出定义长度也不会报错,而PostgreSQL会严格执行长度校验,这是本地正常、线上报错的底层原因。 - 报错提示的
character varying(20)限制,不是你当前模型定义的长度,而是线上PostgreSQL数据库里该表的实际字段长度还停留在旧版本,你删除本地迁移文件重新生成的操作并没有同步到线上数据库。
排查步骤
连接线上PostgreSQL确认表结构
通过Heroku CLI直接连接线上数据库:heroku pg:psql
进入数据库命令行后执行以下命令查看fresh_leads_model表的实际字段定义:\d fresh_leads_model
查看输出结果里所有varchar类型字段的长度限制,一定会找到某一个字段的max_length被设置为20,这就是报错的直接来源。确认迁移执行状态
执行以下命令查看线上迁移记录,确认你最新的模型迁移是否已经成功执行:heroku run python manage.py showmigrations
检查对应应用下的迁移文件是否全部标记为已执行(前面带[X])。
修复方案
方案1:无历史数据/可清空测试数据场景
- 清理线上旧数据与迁移记录
- 进入线上数据库命令行后删除旧表:
DROP TABLE fresh_leads_model CASCADE; - 清理Django迁移记录表中对应应用的旧迁移记录:
DELETE FROM django_migrations WHERE app='替换为你的应用名称';
- 本地重新生成并推送迁移文件
- 本地删除应用下
migrations目录内除了__init__.py之外的所有文件 - 执行本地迁移生成命令:
python manage.py makemigrations 替换为你的应用名称 - 将新生成的迁移文件提交并推送到Heroku
- 执行线上迁移
heroku run python manage.py migrate
方案2:有正式数据不可清空场景
直接新建一个单独的迁移文件修改对应字段的长度,推送后执行线上迁移即可:
# 新建的迁移文件内容示例 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('你的应用名称', '上一个迁移文件的文件名'), ] operations = [ migrations.AlterField( model_name='fresh_leads_model', name='对应长度为20的字段名', field=models.CharField(max_length=250), ), ]
额外优化建议
你当前用pd.read_csv读取CSV时指定了names参数,如果你的CSV文件本身自带表头,会导致表头行被当做第一行数据插入,部分表头字段的长度可能超出限制,建议确认CSV结构后按需增加header=0参数跳过表头。
如果执行完上述操作还是报错,可以在bulk_create代码之前增加字段长度校验的调试代码,快速定位超长字段:
for i in bulk_data: for k, v in i.items(): if len(str(v)) > 20: print(f"超长字段:{k}, 值:{v}, 长度:{len(str(v))}")
内容的提问来源于stack exchange,提问作者djangodeveloper
相关产品推荐
相关产品推荐

