Django执行migrate命令报错:django_content_type表已存在,删表后仍异常
解决Django migrate时
django_content_type表已存在的问题 我之前也碰到过一模一样的坑!执行python manage.py migrate时反复提示django_content_type表已存在,哪怕手动删了表再跑命令还是报错,简直头大。先把你遇到的核心报错信息明确列出来:
Apply all migrations: admin, auth, bridge, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial...Traceback (most recent call last): File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/django/db/backends/utils.py", line 83, in _execute return self.cursor.execute(sql) File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/django/db/backends/mysql/base.py", line 71, in execute return self.cursor.execute(query, args) File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/MySQLdb/cursors.py", line 250, in execute self.errorhandler(self, exc, value) File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler raise errorvalue File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/MySQLdb/cursors.py", line 247, in execute res = self._query(query) File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/MySQLdb/cursors.py", line 411, in _query rowcount = self._do_query(q) File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/MySQLdb/cursors.py", line 374, in _do_query db.query(q) File "/usr/share/nginx/html/django_env/lib/python3.4/site-packages/MySQLdb/connections.py", line 277, in query _mysql.connection.query(self, query) _mysql_exceptions.OperationalError: (1050, "Table 'django_content_type' already exists")
本质原因是Django的迁移状态和实际数据库状态不一致:Django靠django_migrations表记录哪些迁移已经执行,哪怕你删了django_content_type表,如果django_migrations里没有contenttypes初始迁移的记录,migrate还是会尝试重新创建表;反之如果记录存在但表被删了,也会出冲突。下面是几个靠谱的解决办法:
方法一:标记contenttypes初始迁移为已完成(最快)
直接告诉Django“这个迁移已经执行过了”,不用真的修改数据库表:
python manage.py migrate --fake contenttypes 0001_initial
跑完这条命令后,再正常执行全量迁移:
python manage.py migrate
这个方法只更新django_migrations里的状态记录,适合表结构本身已经正确的情况。
方法二:彻底清理迁移状态(适合复杂冲突)
如果上面的方法没用,就来个彻底的重置:
- 登录你的MySQL数据库,手动删除所有Django系统相关的表:
DROP TABLE IF EXISTS django_content_type; DROP TABLE IF EXISTS django_migrations; DROP TABLE IF EXISTS django_admin_log; DROP TABLE IF EXISTS auth_permission; DROP TABLE IF EXISTS auth_group_permissions; DROP TABLE IF EXISTS auth_group; DROP TABLE IF EXISTS auth_user_groups; DROP TABLE IF EXISTS auth_user_user_permissions; DROP TABLE IF EXISTS auth_user; DROP TABLE IF EXISTS django_session;
- 回到项目,删除每个app下
migrations文件夹里除了__init__.py之外的所有文件(别删__init__.py!) - 重新生成迁移文件并执行:
python manage.py makemigrations python manage.py migrate
方法三:检查数据库权限(容易忽略的点)
有时候你以为删了表,但实际上因为数据库用户没有DROP TABLE权限,表根本没被删掉。可以手动登录数据库执行DROP TABLE IF EXISTS django_content_type;,确认表确实被删除后再跑migrate命令。
内容的提问来源于stack exchange,提问作者sukhdev_mathur
相关产品推荐
相关产品推荐

