You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行squashmigrations后无法重建Django数据库的问题求助

问题:Django squashmigrations后重建数据库执行migrate/makemigrations报错

我在Django中执行了squashmigrations操作,之后删除数据库从头重建(从GitHub拉取仓库重建项目时也会遇到相同问题)。运行python manage.py makemigrations或python manage.py migrate时出现如下错误:

(venv)  meal_plan   main  python manage.py makemigrations
Traceback (most recent call last):
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 357, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such table: meal_plan_recipe

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/manage.py", line 22, in <module>
    main()
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/management/base.py", line 402, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/management/base.py", line 443, in execute
    self.check()
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/management/base.py", line 475, in check
    all_issues = checks.run_checks(
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/checks/registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/checks/urls.py", line 42, in check_url_namespaces_unique
    all_namespaces = _load_all_namespaces(resolver)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/core/checks/urls.py", line 61, in _load_all_namespaces
    url_patterns = getattr(resolver, "url_patterns", [])
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 715, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 708, in urlconf_module
    return import_module(self.urlconf_name)
  File "/Users/enricobonardi/.pyenv/versions/3.10.7/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/config/urls.py", line 9, in <module>
    path("", include("meal_plan.urls", namespace="mealplan")),
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/urls/conf.py", line 38, in include
    urlconf_module = import_module(urlconf_module)
  File "/Users/enricobonardi/.pyenv/versions/3.10.7/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/meal_plan/urls.py", line 5, in <module>
    from . import views
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/meal_plan/views.py", line 11, in <module>
    from .forms import MealPlanForm, RecipeSimpleForm
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/meal_plan/forms.py", line 26, in <module>
    class RecipeSimpleForm(forms.ModelForm):
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/meal_plan/forms.py", line 38, in RecipeSimpleForm
    RECIPES = [(x.id, x.title) for x in Recipe.objects.all()]
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/models/query.py", line 394, in __iter__
    self._fetch_all()
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/models/query.py", line 1866, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/models/query.py", line 87, in __iter__
    results = compiler.execute_sql(
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1398, in execute_sql
    cursor.execute(sql, params)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 103, in execute
    return super().execute(sql, params)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/enricobonardi/CODING/TESTING/meal_plan/venv/lib/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 357, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: meal_plan_recipe
(venv)  ✘  meal_plan   main  

meal_plan/models.py代码

from django.conf import settings
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.urls import reverse

User = settings.AUTH_USER_MODEL

# ---------Stagionality----------#
class Month(models.Model):
    name = models.CharField(max_length=25)

    class Meta:
        ordering = ("id",)
        verbose_name = "mese"
        verbose_name_plural = "mesi"

    def __str__(self):
        return self.name

class VegetableItem(models.Model):
    class Types(models.IntegerChoices):
        VERDURA = 1
        FRUTTA = 2

    name = models.CharField(max_length=100)
    type = models.SmallIntegerField(choices=Types.choices, default=Types.VERDURA)
    description = models.TextField(blank=True)
    seasonality = models.ManyToManyField(Month, verbose_name="stagionalità")
    image = models.ImageField(upload_to="vegetableitems", default="vegetableitems/default.png")

    class Meta:
        verbose_name = "alimento stagionale"
        verbose_name_plural = "alimenti stagionali"

    def __str__(self):
        return self.name
# ---------END of Stagionality----------#

# ---------MealPlan----------#
class Day(models.TextChoices):
    LUNEDI = "LUN", "Lunedì"
    MARTEDI = "MAR", "Martedì"
    MERCOLEDI = "MER", "Mercoledì"
    GIOVEDI = "GIO", "Giovedì"
    VENERDI = "VEN", "Venerdì"
    SABATO = "SAB", "Sabato"
    DOMENICA = "DOM", "Domenica"

class Type(models.IntegerChoices):
    COLAZIONE = 1
    SPUNTINO = 2
    PRANZO = 3
    MERENDA = 4
    CENA = 5

class MealPlan(models.Model):
    title = models.CharField(max_length=100)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self) -> str:
        return self.title

    class Meta:
        verbose_name_plural = "mealplan"

    def get_absolute_url(self):
        return reverse("mealplan:mealplan_detail", kwargs={"pk": self.pk})

class Meal(models.Model):
    day = models.CharField(max_length=3, choices=Day.choices, default=Day.LUNEDI, verbose_name="giorno")
    type = models.IntegerField(choices=Type.choices)
    mealplan = models.ForeignKey(MealPlan, on_delete=models.CASCADE)

    class Meta:
        verbose_name = "pasto"
        verbose_name_plural = "pasti"

    def __str__(self) -> str:
        return f"{self.mealplan} ({self.get_day_display()} - {self.get_type_display()})"

class Measure(models.IntegerChoices):
    ML = 1
    G = 2
    UNIT = 3

class Recipe(models.Model):
    title = models.CharField(max_length=100)
    method = models.TextField(blank=True)
    meals = models.ManyToManyField(Meal)

    class Meta:
        verbose_name = "ricetta"
        verbose_name_plural = "ricette"

    def __str__(self) -> str:
        return self.title

class Ingredient(models.Model):
    name = models.CharField(max_length=100)
    quantity = models.SmallIntegerField(blank=True)
    measure = models.IntegerField(choices=Measure.choices, default=Measure.G)
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, null=True)

@receiver(post_save, sender=MealPlan)
def mealplan_post_save_receiver(sender, instance, created, *args, **kwargs):
    if created:
        mealplan = instance
        days_of_the_week = Meal._meta.get_field("day").choices
        days = [label for label, day in days_of_the_week]
        for day in days:
            for type in range(1, 6):
                meal = Meal.objects.create(mealplan=mealplan, day=day, type=type)
                meal.save()
# ---------END of MealPlan----------#

我曾按照教程重置原仓库的迁移,但没有效果。


问题根源

错误栈明确指向:在RecipeSimpleForm类定义阶段,代码直接执行了Recipe.objects.all()查询数据库。Django执行makemigrations或migrate时会加载URL配置,进而导入视图、表单,此时数据库还未创建meal_plan_recipe表,导致触发OperationalError。

解决步骤

1. 修复表单的数据库查询时机

不要在类定义阶段直接查询数据库,改用以下两种方式之一:

方式一:使用ModelChoiceField(推荐)

如果是要选择Recipe实例,直接用Django内置的ModelChoiceField,它会自动处理查询集:

# meal_plan/forms.py
from django import forms
from .models import Recipe

class RecipeSimpleForm(forms.ModelForm):
    # 替换原来的RECIPES和自定义选择字段
    recipe = forms.ModelChoiceField(
        queryset=Recipe.objects.all(),
        empty_label="请选择食谱",
        label="食谱"
    )

    class Meta:
        model = # 你的目标模型
        fields = # 字段列表

方式二:在表单__init__方法中动态加载选项

如果必须自定义choices格式,在表单实例化时再查询数据库:

# meal_plan/forms.py
from django import forms
from .models import Recipe

class RecipeSimpleForm(forms.ModelForm):
    # 先定义字段,不设置choices
    your_field_name = forms.ChoiceField(choices=[], label="食谱")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 实例化时才查询数据库
        self.fields['your_field_name'].choices = [(x.id, x.title) for x in Recipe.objects.all()]

    class Meta:
        model = # 你的目标模型
        fields = # 字段列表

2. 重新执行迁移初始化

  • 删除数据库文件(如db.sqlite3)
  • 删除meal_plan/migrations/目录下除__init__.py外的所有文件
  • 执行命令:
    python manage.py makemigrations
    python manage.py migrate
    

内容的提问来源于stack exchange,提问作者WEBBOgrafico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:50:35