Django1.8+Python2.7.11+MySQL首次迁移遇ProgrammingError报错
这个错误我之前帮朋友排查过,大概率是版本兼容性的问题——毕竟Django 1.8和Python 2.7都是比较老旧的版本,和新的MySQL服务器适配很容易出问题。给你几个针对性的排查和解决方向:
检查MySQL服务器版本
Django 1.8官方明确只支持MySQL 5.5到5.7版本,如果你的MySQL是8.0及以上,那肯定会触发这类语法兼容问题。MySQL 8.0不仅修改了不少SQL语法规则,还更换了默认的认证插件,老版本Django完全不兼容这种新特性。
这种情况要么把MySQL降级到5.7版本,要么升级Django到1.11(这是Python 2.7能支持的最高Django版本)。不过升级Django可能需要调整现有代码,建议优先考虑降级MySQL。确认数据库驱动版本
Python 2.7连接MySQL常用的驱动是MySQL-python(也就是MySQLdb)或者mysqlclient,要确保驱动版本和Django 1.8、MySQL版本完全匹配:- 如果用
MySQL-python,最高只能选1.2.5版本,它只支持到MySQL 5.7; - 如果用
mysqlclient,在Python 2.7上要选1.3.14及以下的版本,更高版本已经不再支持Python 2.7。
你可以用pip freeze查看当前驱动版本,不合适的话卸载重装:
pip uninstall MySQL-python mysqlclient pip install mysqlclient==1.3.14- 如果用
调整数据库配置的OPTIONS参数
有时候MySQL的sql_mode设置过于严格,会导致Django自动生成的SQL语句报错。你可以在settings.py的数据库配置里加上初始化命令,强制设置兼容的sql_mode:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '你的数据库名', 'USER': '数据库用户名', 'PASSWORD': '数据库密码', 'HOST': 'localhost', 'PORT': '3306', 'OPTIONS': { 'init_command': "SET sql_mode='STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'", 'charset': 'utf8', }, } }这个配置能让MySQL兼容老版本的SQL语法,避免因为模式严格触发的语法错误。
排查迁移文件的自定义SQL
虽然你说代码没问题,但如果是自己开发的app里有自定义迁移脚本,里面的SQL语句可能不符合当前MySQL的语法规则。你可以先尝试只迁移Django自带的核心app(比如auth、admin),看看会不会报错:python manage.py migrate auth如果这个命令能成功执行,那问题大概率出在你自己的app迁移文件里,需要逐行检查自定义SQL语句的语法。
内容的提问来源于stack exchange,提问作者108

