在我的 Django 项目上运行 python manage.py migrate
时,我收到以下错误:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/hari/project/env/local/lib/python2.7/site- packages/django/core/management/__init__.py", line 363, in execute_from_command_line
utility.execute()
File "/home/hari/project/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 355, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/hari/project/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/hari/project/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/home/hari/project/env/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 86, in handle
executor.loader.check_consistent_history(connection)
File "/home/hari/project/env/local/lib/python2.7/site-packages/django/db/migrations/loader.py", line 298, in check_consistent_history
connection.alias,
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency account.0001_initial on database 'default'.
我有一个如下的用户模型:
class User(AbstractUser):
place = models.CharField(max_length=64, null=True, blank=True)
address = models.CharField(max_length=128, null=True, blank=True)
我怎么解决这个问题?
'ipn', '__latest__'
的迁移。我刚刚检查了使用 select * from django_migrations
应用的订单或迁移,然后将 __latest__
更改为 'ipn', '0007_auto_20160219_1135'
,问题就消失了。
由于您使用的是自定义 User 模型,因此您可以先注释掉
INSTALLED_APPS = [
...
#'django.contrib.admin',
...
]
在您的 Installed_Apps 设置中。然后运行
python manage.py migrate.
完成后取消注释
'django.contrib.admin'
让我们首先解决此页面上大多数答案的问题:
如果您正确使用 Django 的迁移系统,则永远不必删除数据库,并且一旦提交迁移,就永远不要删除它们
现在,最适合您的解决方案取决于许多因素,包括您对 Django 的经验、您对迁移系统的理解程度以及数据库中数据的价值。
简而言之,有两种方法可以解决任何迁移错误。
选择核选项。警告:仅当您独自工作时,这只是一种选择。如果其他人依赖于现有的迁移,您不能只删除它们。删除所有迁移,并使用 python3 -m manage makemigrations 重建一个新的集合。这应该可以消除您在迁移中遇到的任何依赖关系或不一致问题。删除整个数据库。这将消除您在实际数据库架构与基于迁移历史记录的架构之间存在的任何不一致问题,并将消除您在迁移历史记录与之前的迁移文件之间存在的任何不一致问题 [这就是InconsistentMigrationHistory 正在抱怨]。使用 python3 -m manage migrate 重新创建您的数据库模式 确定错误的原因并解决它,因为(根据经验)原因几乎可以肯定是您所做的一些愚蠢的事情。 (一般是由于不了解如何正确使用迁移系统造成的)。根据我造成的错误,分为三类。与迁移文件不一致。当多人在一个项目上工作时,这是很常见的。希望您的更改不会冲突,并且 makemigrations --merge 可以解决这个问题,否则有人将不得不将他们的迁移回滚到分支点才能解决这个问题。您的架构和迁移历史记录之间的不一致。为了管理这个,有人要么手动编辑数据库模式,要么删除迁移。如果他们删除了迁移,则恢复他们的更改并对他们大喊大叫;如果其他人依赖迁移,则永远不要删除迁移。如果他们手动编辑了数据库模式,请恢复他们的更改,然后对他们大喊大叫; Django 正在管理数据库模式,没有其他人。您的迁移历史记录和迁移文件之间的不一致。 [这是提问者遇到的 InconsistentMigrationHistory 问题,也是我到达此页面时遇到的问题]。为了管理这个,有人手动弄乱了 django_migrations 表,或者在应用迁移后删除了迁移。要解决此问题,您将必须弄清楚不一致是如何产生的并手动解决它。如果您的数据库架构是正确的,而只是您的迁移历史记录是错误的,您可以手动编辑 django_migrations 表来解决这个问题。如果您的数据库架构错误,那么您还必须手动编辑它以使其符合应有的状态。
根据您对问题的描述和您选择的答案,我假设您是独自工作,是 Django 的新手,并且不关心您的数据。因此,核选项可能适合您。
如果您不是这种情况并且上面的文字看起来像乱码,那么我建议您向 Django User's Mailing List 寻求帮助。那里有非常乐于助人的人,他们可以帮助您解决您所处的具体问题。
有信心,您可以在不使用核的情况下解决此错误!
00XX_auto
迁移的迁移系统应用程序 B 的 0001_initial
迁移在它的依赖项之前以某种方式应用了!
'A' '00XX_auto'
添加到 django_migrations
表中,这样我的历史记录就会反映出该迁移中的更改已被应用。复杂的,但一旦你解决了问题就没有那么难了。
managed = False
。当我决定让 ORM 完成它的工作并转向托管模型(作为让我的测试运行的一种方式)时,我所有的“乐趣”就开始了。
replaces
任何内容。当有人需要找出无数 0002 迁移中的哪一个是真正的迁移时,保留旧的迁移只会让您的团队陷入困境。
数据库中的 django_migrations 表是不一致的原因,仅从本地路径删除所有迁移将不起作用。
您必须从数据库中截断 django_migrations 表,然后再次尝试应用迁移。它应该可以工作,但如果没有,则再次运行 makemigrations 然后迁移。
注意:不要忘记备份您的数据。
0001_initial
迁移,而新版本没有应用。如果您想要一个干净的 prod 迁移历史记录而不进行不必要的更改,那么在将这些迁移发送到 prod 之前在本地开发中删除和重新生成迁移对我来说似乎很好。其他评论和答案指出删除/清除迁移不适用于 prod 数据库,这是真的。
根据 django 文档中的建议,在我添加自定义用户模型后,这发生在我的一个新项目中。
这是我为解决问题所做的。
删除数据库 db.sqlite3。删除应用程序/迁移文件夹。
根据@jackson,暂时注释掉 django.contrib.admin。
INSTALLED_APPS = [
...
#‘django.contrib.admin’,
...
]
还要注释掉 urls.py 中的管理站点:
urlpatterns = [
path('profile/', include('restapp.urls')),
#path('admin/', admin.site.urls),
]
如果不注释掉路径('admin/'),运行时会报错“LookupError: No installed app with label 'admin'”
python manage.py migrate
迁移完成后,取消注释上述两个。
这里如何正确解决这个问题。
在项目内的迁移文件夹中执行以下步骤:
删除 _pycache_ 和 0001_initial 文件。从根目录中删除 db.sqlite3(注意所有数据都会消失)。在终端运行: python manage.py makemigrations python manage.py migrate
瞧。
sqllite
,它是我们服务器中的 MySQL。在不丢失数据的情况下,有什么更好的方法。
问题
django.db.migrations.exceptions.InconsistentMigrationHistory:迁移 admin.0001_initial 在其依赖 account.0001_initial 之前应用于数据库“默认”。
所以我们可以先迁移数据库而无需管理员(admin.0001_initial)。
在其依赖项迁移后,执行命令迁移 admin.0001_initial
。
解决方案
从 settings.py 中的 INSTALLED_APPS 中删除 'django.contrib.admin'。执行命令:
Python manage.py makemigrations appname Python manage.py migrate appname
在 settings.py 文件中将 'django.contrib.admin' 添加到 INSTALLED_APPS。再次执行命令:
Python manage.py makemigrations appname Python manage.py migrate appname
LookupError: No installed app with label 'admin'.
在执行任何其他步骤之前,请备份您的数据库。然后再次备份。
删除任何自定义用户模型代码,在设置中禁用您的自定义模型和应用程序,然后:
python manage.py dumpdata auth --natural-primary --natural-foreign > auth.json
python manage.py migrate auth zero # This will also revert out the admin migrations
然后添加您的自定义模型,在设置中进行设置,然后重新启用该应用程序。确保您还没有在此应用上进行迁移。
然后:
python manage.py makemigrations <your-app>
python manage.py migrate
python manage.py loaddata auth.json # Assumes your user-model isn't TOO dissimilar to the standard one.
完毕!
通过在 settings.py 迁移之前评论 app admin 解决
django.contrib.admin
在 urls.py 中,
('admin/', admin.site.urls)
迁移后取消注释
当您对默认用户模型进行一些更改或通过 abstractuser 制作自定义用户模型时,很多时候您将面临该错误
1:请记住,当我们创建超级用户时,我们需要用户名和密码才能登录,但如果您转换了 USERNAME_FIELD = 'email' 那么现在您无法使用用户名和密码登录,因为您的用户名字段已转换为电子邮件......
https://i.stack.imgur.com/7JITH.png
https://i.stack.imgur.com/fhTM3.png
2:这就是为什么在迁移过程中创建自定义用户模型后会抛出错误,所以为了解决它首先添加 AUTH_USER_MODEL = 'appname.custommodelname' (appname 是您定义自定义用户模型的应用程序名称,自定义模型名称是您在 settings.py 中提供给自定义用户模型的模型) 3:然后删除创建该自定义用户模型的应用程序的迁移文件夹,然后删除项目的数据库 db.sqlite3 4:现在运行迁移 python 管理。 py makemigrations appname(您定义自定义用户模型的那个应用程序名称) 5:然后通过 python manage.py migrate 迁移它 6:就是这样 现在它完成了
只需删除所有 migrations
文件夹、__pycache__
、.pyc
文件:
find . | grep -E "(__pycache__|\.pyc|\.pyo$|migrations)" | xargs rm -rf
然后,运行:
python manage.py makemigrations
python manage.py migrate
就我而言,问题在于 pytest 启动,我只是将 --reuse-db
更改为 --create-db
,运行 pytest,然后将其改回。这解决了我的问题
只需删除 sqlite 文件或运行刷新数据库“python manage.py flush”,然后分别运行 makemigrations 和 migrate 命令。
当您创建一个新的 Django 项目并运行时
python manage.py 迁移
默认情况下,Django 将为您创建 10 个表,其中包括一个 auth_user 表和两个以 auth_user 开头的表。
当你想创建一个继承自 AbstractUser 的自定义用户模型时,你会遇到这个问题,错误信息如下:
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency account.0001_initial on database 'default'.
我通过删除整个数据库并创建一个新数据库来解决这个问题。这取代了我提到的三个表。
您的错误本质上是:
Migration "B" is applied before its dependency "A" on database 'default'.
健全性检查:首先,打开您的数据库并查看“django_migrations”表中的记录。记录应按时间顺序列出(例如:A、B、C、D...)。
确保错误中列出的“A”迁移的名称与数据库中列出的“A”迁移的名称匹配。 (如果您以前手动、编辑或删除或重命名迁移文件,它们可能会有所不同)
要解决此问题,请在数据库中重命名迁移 A. 或重命名文件名。但请确保更改与您团队中其他开发人员在其数据库中的内容相匹配(或更改与您的生产数据库中的内容相匹配)
INSTALLED_APPS
的顺序似乎很重要。如果你总是把你最近的作品放在列表的顶部/开头,它们总是会被正确加载到 django.contrib.admin 中。将我的作品移到 INSTALLED_APPS
列表的开头为我解决了这个问题。 Kun Shi 的解决方案可能奏效的原因可能是它以不同的顺序运行迁移。
可以直接删除db.sqlite3,然后自动生成迁移新数据库。它应该修复它。
rm sqlite3.db
python manage.py makemigrations
python manage.py migrate
如果您正在处理空数据库,则可以在任何其他应用程序迁移之前运行帐户应用程序的迁移。
$ ./manage.py migrate account
接着:
$ ./manage.py migrate
如何修复(不删除迁移文件夹或整个数据库)
备份您的数据库 在 INSTALLED_APPS 和 AUTH_USER_MODEL = 'account.User' 中注释掉您的应用程序 在您的 settings.py python manage.py admin zero 撤消步骤 2 python manage.py migrate
为什么会出现这个问题?
django 管理应用程序依赖于 AUTH_USER_MODEL
,这是您创建 django 项目时的默认身份验证模型。
如果您在更改 AUTH_USER_MODEL
之前迁移项目模型,django admin 应用程序会将迁移应用为 django auth 模型依赖项。但是,您更改了该依赖性,并希望再次迁移模型。所以,问题就出现在这里; admin 模型在其依赖项之前应用,现在是您的 User 模型。因此,您应该恢复管理模型迁移,然后再试一次。
由于您使用的是自定义 User 模型,因此您可以先注释掉
INSTALLED_APPS = [
...
#'django.contrib.admin',
...
]
在您的 Installed_Apps 设置中。还有评论
urlpatterns = [
# path('admin/', admin.site.urls)
....
....
]
在你的基本 urls.py
然后运行
python manage.py migrate.
完成后取消注释
'django.contrib.admin'
和
path('admin/', admin.site.urls)
首先删除所有迁移和 db.sqlite3 文件并按照以下步骤操作:
$ ./manage.py makemigrations myapp
$ ./manage.py squashmigrations myapp 0001(may be differ)
最后删除旧的迁移文件。
$ ./manage.py migrate
如果在您尝试创建自己的用户模型而不是标准模型时出现该异常,请遵循该instruction
我发现我的问题已通过逐步遵循该说明解决:
创建一个与 auth.User 相同的自定义用户模型,将其命名为 User(如此多对多的表保持相同的名称)并设置 db_table='auth_user'(因此它使用同一个表)丢弃所有迁移重新创建一个新的一组迁移 牺牲一只鸡,如果你着急,也许两只;还备份您的数据库 截断 django_migrations 表 假应用新的迁移集 取消设置 db_table,对自定义模型进行其他更改,生成迁移,应用它们 强烈建议在强制外键约束的数据库上执行此操作.不要在笔记本电脑上的 SQLite 上尝试这个并期望它在服务器上的 Postgres 上工作!
如果您在 settings.py 中设置 AUTH_USER_MODEL,如下所示:
AUTH_USER_MODEL = 'custom_user_app_name.User'
您应该在运行 makemigration 和 migrate 命令之前注释掉这一行。然后您可以再次取消注释该行。
accounts.CustomUser.groups: (fields.E304) Reverse accessor for 'CustomUser.groups' clashes with reverse accessor for 'User.groups'. HINT: Add or change a related_name argument to the definition for 'CustomUser.groups' or 'User.groups'.
当您创建一个新项目并且没有应用程序时,您运行
python manage.py migrate
默认情况下,Django 将创建 10 个表。
如果您想创建一个继承自 AbstractUser
的客户用户模型,您将遇到以下问题:
django.db.migrations.exceptions.InconsistentMigrationHistory:迁移 admin.0001_initial 在其依赖 account.0001_initial 之前应用于数据库“默认”。
最后,我删除了我的整个数据库并运行
我在从 Wagtail 2.0 迁移到 2.4 时遇到了这种情况,但是当第三方应用程序在您当前版本之后但在您要迁移到的版本之前压缩迁移时,我已经看到过几次。
在这种情况下,令人震惊的简单解决方案至少是:
./manage.py migrate
./manage.py makemigrations
./manage.py migrate
即在尝试进行迁移之前运行一次迁移。
除了用户错误之外,还有另一个可能导致此类问题的原因:a known issue with Django 涉及压缩迁移。
我们有一系列在 Python 2.7 + Django 1.11 中运行良好的迁移。运行 makemigrations
或 migrate
始终按应有的方式运行,等等,即使(出于测试目的)新创建数据库时也是如此。
然而,当我们将项目迁移到 Python 3.6(当前使用相同的 Django 1.11)时,我一直在试图弄清楚为什么相同的迁移仅在第一次运行时才适用。之后,任何运行 makemigrations
甚至只是运行 migrate
的尝试都会导致错误:
django.db.migrations.exceptions.InconsistentMigrationHistory
其中迁移 foo.0040-thing
在其依赖项 foo.0038-something-squashed-0039-somethingelse
之前应用(我们只是碰巧有一个被压缩的迁移......其余的要简单得多)。
有一段时间困扰我的是为什么这只发生在 Python 3 上。如果数据库确实不一致,这应该一直发生。迁移在第一次应用时似乎工作得非常好,这同样令人困惑。
经过大量搜索(包括目前的问答线程),我偶然发现了 the aforementioned Django bug report。我们的 squash 迁移确实在 replaces
行中使用了 b
前缀(例如,replaces = [(b'', 'foo.0038-defunct'),.......]
一旦我从 replaces
行中删除了 b
前缀,它就一切正常。
如果您在初始迁移后扩展用户模型,大多数情况下都会出现此问题。因为每当您扩展 Abstract 用户时,它都会创建模型中存在的基本字段,例如电子邮件、名字等。
甚至这也适用于 django 中的任何抽象模型。
因此,一个非常简单的解决方案是创建一个新数据库然后应用迁移或删除 [在这种情况下,您所有的数据都将被删除。] 相同的数据库并重新应用迁移。
我必须将我的数据库放到然后运行 makemigrations 并再次迁移,以便我自己解决这个问题。
删除迁移文件夹和 db.sqlite3 并输入 cmd python manage.py makemigrations
django.db.migrations.exceptions.InconsistentMigrationHistory #关于创建自定义用户模型
我今天遇到了同样的问题,上述解决方案都没有奏效,然后我想使用以下命令从本地 PostgreSQL 数据库中删除所有数据
-- Drop everything from the PostgreSQL database.
DO $$
DECLARE
q TEXT;
r RECORD;
BEGIN
-- triggers
FOR r IN (SELECT pns.nspname, pc.relname, pt.tgname
FROM pg_catalog.pg_trigger pt, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace AND pc.oid=pt.tgrelid
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pt.tgisinternal=false
) LOOP
EXECUTE format('DROP TRIGGER %I ON %I.%I;',
r.tgname, r.nspname, r.relname);
END LOOP;
-- constraints #1: foreign key
FOR r IN (SELECT pns.nspname, pc.relname, pcon.conname
FROM pg_catalog.pg_constraint pcon, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace AND pc.oid=pcon.conrelid
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pcon.contype='f'
) LOOP
EXECUTE format('ALTER TABLE ONLY %I.%I DROP CONSTRAINT %I;',
r.nspname, r.relname, r.conname);
END LOOP;
-- constraints #2: the rest
FOR r IN (SELECT pns.nspname, pc.relname, pcon.conname
FROM pg_catalog.pg_constraint pcon, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace AND pc.oid=pcon.conrelid
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pcon.contype<>'f'
) LOOP
EXECUTE format('ALTER TABLE ONLY %I.%I DROP CONSTRAINT %I;',
r.nspname, r.relname, r.conname);
END LOOP;
-- indicēs
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind='i'
) LOOP
EXECUTE format('DROP INDEX %I.%I;',
r.nspname, r.relname);
END LOOP;
-- normal and materialised views
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind IN ('v', 'm')
) LOOP
EXECUTE format('DROP VIEW %I.%I;',
r.nspname, r.relname);
END LOOP;
-- tables
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind='r'
) LOOP
EXECUTE format('DROP TABLE %I.%I;',
r.nspname, r.relname);
END LOOP;
-- sequences
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind='S'
) LOOP
EXECUTE format('DROP SEQUENCE %I.%I;',
r.nspname, r.relname);
END LOOP;
-- extensions (only if necessary; keep them normally)
FOR r IN (SELECT pns.nspname, pe.extname
FROM pg_catalog.pg_extension pe, pg_catalog.pg_namespace pns
WHERE pns.oid=pe.extnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
) LOOP
EXECUTE format('DROP EXTENSION %I;', r.extname);
END LOOP;
-- aggregate functions first (because they depend on other functions)
FOR r IN (SELECT pns.nspname, pp.proname, pp.oid
FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pns, pg_catalog.pg_aggregate pagg
WHERE pns.oid=pp.pronamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pagg.aggfnoid=pp.oid
) LOOP
EXECUTE format('DROP AGGREGATE %I.%I(%s);',
r.nspname, r.proname,
pg_get_function_identity_arguments(r.oid));
END LOOP;
-- routines (functions, aggregate functions, procedures, window functions)
IF EXISTS (SELECT * FROM pg_catalog.pg_attribute
WHERE attrelid='pg_catalog.pg_proc'::regclass
AND attname='prokind' -- PostgreSQL 11+
) THEN
q := 'CASE pp.prokind
WHEN ''p'' THEN ''PROCEDURE''
WHEN ''a'' THEN ''AGGREGATE''
ELSE ''FUNCTION''
END';
ELSIF EXISTS (SELECT * FROM pg_catalog.pg_attribute
WHERE attrelid='pg_catalog.pg_proc'::regclass
AND attname='proisagg' -- PostgreSQL ≤10
) THEN
q := 'CASE pp.proisagg
WHEN true THEN ''AGGREGATE''
ELSE ''FUNCTION''
END';
ELSE
q := '''FUNCTION''';
END IF;
FOR r IN EXECUTE 'SELECT pns.nspname, pp.proname, pp.oid, ' || q || ' AS pt
FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pns
WHERE pns.oid=pp.pronamespace
AND pns.nspname NOT IN (''information_schema'', ''pg_catalog'', ''pg_toast'')
' LOOP
EXECUTE format('DROP %s %I.%I(%s);', r.pt,
r.nspname, r.proname,
pg_get_function_identity_arguments(r.oid));
END LOOP;
-- nōn-default schemata we own; assume to be run by a not-superuser
FOR r IN (SELECT pns.nspname
FROM pg_catalog.pg_namespace pns, pg_catalog.pg_roles pr
WHERE pr.oid=pns.nspowner
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast', 'public')
AND pr.rolname=current_user
) LOOP
EXECUTE format('DROP SCHEMA %I;', r.nspname);
END LOOP;
-- voilà
RAISE NOTICE 'Database cleared!';
END; $$;
在此之后,您可以运行 django 命令进行迁移
python manage.py makemigrations
python manage.py migrate
这绝对会奏效。谢谢你。
从已安装的应用程序中评论 django.contrib.admin 并评论路径('admin/', admin.site.urls),然后重新运行 makemigrations 然后迁移。它将解决您的问题。欲了解更多信息,请访问 here
不定期副业成功案例分享