Django 声称首次迁移时迁移历史不一致

问题描述 投票:0回答:4

我已经在一个项目上工作了一段时间,并且在迁移方面没有遇到任何问题。 我决定重置数据库和迁移,我时常这样做。 我删除了所有迁移,重新创建它们,然后重新创建数据库后,应用迁移,此时,我收到错误“

Migration users.0001_initial is applied before its dependency auth.0012_alter_user_first_name_max_length on database 'default'.

现在,

auth.0012_alter_user_first_name_max_length
显然来自
django.contrib.auth
,它是核心django的一部分,所以我不明白为什么我需要在新项目中依赖它的迁移,但是每当我从首先,它添加了对我的用户模型
auth.0012_alter_user_first_name_max_length
的依赖。 我不知道为什么它会这样做,而昨天它显然没有这样做,但我现在必须在迁移之前手动从用户迁移中删除该依赖项。

可能是什么原因造成的。

这是我的 users.models.py 文件。 也许有人能弄清楚它会这样做有什么奇怪的。

from django.contrib.auth.models import AbstractUser
from django.db.models import CharField, EmailField
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from django.contrib.auth.models import UserManager
from django.db.models import Q


# Override UserManager and allow login with both username and email address
class CustomUserManager(UserManager):
    def get_by_natural_key(self, username):
        return self.get(
            Q(**{self.model.USERNAME_FIELD: username}) |
            Q(**{self.model.EMAIL_FIELD: username})
        )


class User(AbstractUser):
    class Meta(object):
        unique_together = ('email',)
    email = EmailField(_('email address'), unique=True, blank=True, max_length=255)
    phone_number = PhoneNumberField(_('Phone number'), blank=True)
    address = CharField(_("Street address"), blank=True, max_length=255)
    city = CharField(_("City"), blank=True, max_length=255)
    state = CharField(_("State"), blank=True, max_length=255)
    zip = CharField(_("ZIP"), blank=True, max_length=255)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['first_name', 'last_name', 'email']
    # for allowing both username and email login
    objects = CustomUserManager()

    def get_absolute_url(self):
        """Get url for user's detail view.

        Returns:
            str: URL for user detail.

        """
        return reverse("users:detail", kwargs={"username": self.username})

python django
4个回答
1
投票

这对我有用

  1. 删除数据库db.sqlite3。
  2. 删除 app/migrations 文件夹。

设置.py:

INSTALLED_APPS = [
...
#'django.contrib.admin',
...
]

urls.py:

urlpatterns = [
    path('profile/', include('restapp.urls')),
    #path('admin/', admin.site.urls),
]

迁移您的表:

python manage.py makemigrations      
python manage.py migrate

取消注释两个网址和这个:

INSTALLED_APPS = [
...
'django.contrib.admin',
...
]

再次:

python manage.py makemigrations      
python manage.py migrate

更多详情请访问..


1
投票

为什么会出现错误?

Django 会在名为

django_migrations
的表中跟踪已运行的迁移。当你运行
migrate
时:

  1. 检查哪些迁移已运行,哪些需要运行
  2. 然后在运行迁移时记录它运行的迁移。

当 django 检测到迁移已经以某种方式运行时,就会引发

InconsistentMigrationHistory
错误,而这本来是不可能的(例如,如果它已经运行,但它的依赖项之一尚未运行)。

我不知道你是如何删除你的数据库的,但显然这个表(

django_migrations
)没有被正确删除,或者自从被擦除以来它已经被篡改了。否则就不会引发此错误。 users.0001_initial已经被应用,而
auth.0012_alter_user_first_name_max_length
还没有应用,这是
非常奇怪
。我真的不确定这是怎么发生的。您对该表进行过手动编辑吗???

如何解决?

如上所述,半删除数据库会导致比上述错误更大的问题。如果某些迁移没有运行,因为 django 认为它们已经应用,而实际上它们没有应用,那么您的代码和数据库可能会完全不同步。确保您已正确完全擦除数据库(特别是

django_migrations
表)。

我可以删除有问题的依赖项吗?

不,这可能会给您带来问题。由于

User
继承自
AbstractUser
,因此它将继承
user_permissions
,这是与
auth.Permission
的多对多字段。 (它还将继承一个带有
auth.Group
的多对多字段)。

为了让您的新迁移正常工作,需要首先等待

auth.Permission
(和
auth.Group
)正确设置,这样才能正确设置多对多字段。在新迁移运行之前需要先运行
contrib.auth
迁移是依赖于
auth_0012...
的原因。

(它是

contrib.auth
中的最后一次迁移,而不是最后一次涉及
Permission
Group
的原因只是
makemigrations
算法的工作方式。它还不够聪明,无法弄清楚要指向哪个迁移,所以它只指向该应用程序中的最后一个。)


0
投票

我在升级到 django 3.1 时遇到过这个问题。这是添加了

auth.0012
迁移的版本。

问题:

我的应用程序的初始迁移具有以下依赖项:

dependencies = [
    ('contenttypes', '__latest__'),
    ('auth', '__latest__'),
    ...
]

由于现在最新的身份验证迁移是

auth.0012
尚未应用,因此应用程序的依赖项未满足并且迁移失败:

django.db.migrations.exceptions.InconsistentMigrationHistory:迁移 dbentry.0001_initial 在数据库“default”上的依赖项 auth.0012_alter_user_first_name_max_length 之前应用

修复:

将身份验证依赖项设置为已应用的最新迁移:在我的例子中为

('auth', '0011_update_proxy_permissions')
。然后迁移将运行并应用
auth.0012
。此时,您可以将依赖项设置回
__latest__
- 尽管这可能意味着下次 django.auth 添加迁移时必须重复此过程。


0
投票

问题出现在django升级到3.1的过程中,该版本添加了auth.0012!要检查本地设置的最新内容,您可以运行

python manage.py showmigrations 

它将显示上次应用的迁移,将上次应用的身份验证迁移添加为 inital0001 迁移文件中的依赖项,然后就可以开始了!

对我来说就是这个

    ('auth', '0006_require_contenttypes_0002'),

显示迁移图像参考

© www.soinside.com 2019 - 2024. All rights reserved.