Django社交站无法接受好友请求,提示no such table: main.users_profile__old错误
错误产生原因
- 核心为 SQLite 版本与 Django 2.1 版本的迁移机制不兼容:SQLite 3.26 及以上版本调整了
ALTER TABLE语句的执行逻辑,修改表结构时会自动生成带__old后缀的临时备份表,迁移完成后自动删除。但 Django 2.1 初始版本未适配该变更,迁移完成后仍保留了对已删除__old表的引用,导致后续数据库操作报错。 - 报错触发点为多对多字段写入操作:在
accept_friend_request视图中调用user1.profile.friends.add(user2.profile)时,需要操作Profile模型中friends多对多字段对应的关联表,残留的表引用会让数据库尝试访问不存在的main.users_profile__old表,最终抛出异常。
解决方法
按适用场景从易到难排序:
场景1:开发阶段、测试数据可删除
直接重置数据库和迁移文件即可:- 删除项目根目录下的
db.sqlite3数据库文件 - 删除所有app下
migrations目录中除__init__.py外的所有文件 - 重新执行迁移命令:
python manage.py makemigrations python manage.py migrate- 重启Django服务后测试功能即可。
- 删除项目根目录下的
场景2:需要保留现有数据、可升级Django版本
该兼容性问题在 Django 2.1.1 及后续版本已被官方修复,直接升级 Django 到对应补丁版即可:pip install django==2.1.15升级完成后重新执行之前失败的迁移,再重启服务即可。
场景3:不能升级Django版本、也不能删除现有数据
可以直接操作SQLite数据库清理残留的表引用:- 命令行连接本地SQLite数据库:
sqlite3 db.sqlite3- 执行SQL语句清理残留:
PRAGMA foreign_keys = OFF; BEGIN TRANSACTION; DROP TABLE IF EXISTS users_profile__old; COMMIT; PRAGMA foreign_keys = ON;- 退出SQLite命令行,重启Django服务即可。
额外优化建议
当前Profile模型的friends多对多字段默认是对称关系,即给A加好友时,A默认也会自动添加当前用户为好友,不需要在视图中手动写两次add操作。如果要保留现有双向添加逻辑,建议给字段显式设置symmetrical=False避免潜在的关联数据冲突:
friends = models.ManyToManyField("self", blank=True, symmetrical=False)
内容的提问来源于stack exchange,提问作者Rohan_buks
相关产品推荐
相关产品推荐

