Django 2.2迁移报错:django.db.utils.OperationalError: no such table
Django Makemigrations 报错:
sqlite3.OperationalError: no such table: catalog_fault 我一眼就揪出问题根源了——你在Django加载URL配置的阶段直接执行了数据库操作,而运行makemigrations这类管理命令时,数据库表还没创建出来,程序自然会报错找不到catalog_fault表。
从报错栈能清晰看到整个触发链:
- 执行
makemigrations时,Django会加载URL配置文件 - 你的
locallibrary/urls.py第60行直接调用了loader.load_db() - 这个方法又触发了
add_game,进而调用add_fault里的Fault.objects.get(...) - 此时数据库里还没有
catalog_fault表,直接抛出不存在的错误
解决方案
1. 给数据加载逻辑加“开关”,避开管理命令
绝对不能在URL模块的顶层直接调用需要访问数据库的代码,得把loader.load_db()的调用改成仅在启动开发服务器时执行,避开makemigrations/migrate这类场景。
修改locallibrary/urls.py:
# 替换原来直接调用loader.load_db()的代码 import sys # 仅当运行runserver命令时才执行数据加载 if len(sys.argv) > 1 and sys.argv[1] == 'runserver': loader.load_db()
2. 先完成数据库迁移,再启动数据加载
如果你的数据加载依赖已存在的表,得先确保表被创建:
- 先临时注释掉URL里的
loader.load_db()调用 - 依次执行以下命令:
python3 manage.py makemigrations python3 manage.py migrate - 恢复上面加了条件判断的
loader.load_db()调用
3. 优化数据加载逻辑的安全性
另外,add_fault里用Fault.objects.get(...)如果找不到对象还会抛出DoesNotExist异常,建议改成get_or_create更稳妥:
def add_fault(fault_name, batch=False): # 用get_or_create替代get,避免找不到对象的异常,同时自动创建不存在的记录 fault, created = Fault.objects.get_or_create(fault__icontains=fault_name) # 后续业务逻辑...
验证步骤
- 按上面的方法修改URL配置里的加载逻辑
- 运行
python3 manage.py makemigrations,此时应该不会再报错 - 运行
python3 manage.py migrate创建所有数据表 - 启动服务器
python3 manage.py runserver,数据加载逻辑会正常执行
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

