Django-CMS在PostgreSQL执行migrate时触发TypeError,SQLite无异常
解决PostgreSQL下Django migrate触发的TypeError问题
这个错误是典型的旧版Django与高版本psycopg2/PostgreSQL不兼容导致的,SQLite环境没问题是因为SQLite的表结构探测逻辑和PostgreSQL完全不同。下面给你一步步的解决方案:
1. 核心原因分析
从错误回溯能看到,问题出在Django的PostgreSQL数据库探测代码里:当调用get_table_description时,旧版Django试图用序列切片/下标访问cursor.description的元素,但高版本psycopg2(2.8+)已经把cursor.description返回的字段描述从元组改成了Column对象,旧代码的访问方式不再适用,因此触发了TypeError。
2. 具体解决方案
方案一:降级psycopg2到兼容版本(最快捷)
Django 1.11.x系列官方仅支持psycopg2 2.7.x版本,如果你安装了更高版本的psycopg2,直接降级即可:
- 先查看当前安装的版本:
pip show django psycopg2-binary - 如果psycopg2版本是2.8或更高,执行降级命令:
pip install psycopg2-binary==2.7.7 --force-reinstall - 重新运行迁移命令:
python manage.py migrate
方案二:升级Django到最新兼容补丁版
如果你的项目允许升级Django,建议升级到1.11系列的最新补丁版本(比如1.11.29),这个版本修复了与高版本psycopg2的兼容性问题:
pip install django==1.11.29 --upgrade
升级完成后再执行migrate命令即可。
方案三:临时修复探测代码(仅紧急情况使用)
如果你暂时无法升级或降级,可以手动修改Django的PostgreSQL探测文件:
- 找到报错文件:
/home/vagrant/.virtualenvs/pmvp/lib/python3.6/site-packages/django/db/backends/postgresql/introspection.py - 找到
get_table_description方法里的列表推导式,把原来的下标访问改成属性访问:
原代码类似:
修改为:return [ {'name': desc[0], 'type_code': desc[1], 'display_size': desc[2], 'internal_size': desc[3], 'precision': desc[4], 'scale': desc[5], 'null_ok': desc[6], } for desc in cursor.description ]return [ {'name': desc.name, 'type_code': desc.type_code, 'display_size': desc.display_size, 'internal_size': desc.internal_size, 'precision': desc.precision, 'scale': desc.scale, 'null_ok': desc.null_ok, } for desc in cursor.description ] - 保存文件后重新运行
migrate。
3. 验证修复
执行完上述任意方案后,重新运行迁移命令:
python manage.py migrate
如果没有报错,说明问题已经解决。
内容的提问来源于stack exchange,提问作者Maruthesh
相关产品推荐
相关产品推荐

