卸载应用A,该应用在一个旧迁移中有依赖于应用B。

4
我正在试图卸载一个名为django-cities的应用程序,但在我的应用程序“places”中,我有一个称为Venue的模型,在迁移0001_initial.py中,该模型与django-citiescities.Subregion模型有一个ForeingKey
我继续从INSTALLED_APPS中删除 django-cities,但是我收到了以下错误:
Traceback (most recent call last):
  File "/home/d/.virtualenvs/beplay/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 227, in wrapper
    fn(*args, **kwargs)
  File "/home/d/.virtualenvs/beplay/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 128, in inner_run
    self.check_migrations()
  File "/home/d/.virtualenvs/beplay/local/lib/python2.7/site-packages/django/core/management/base.py", line 422, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
  File "/home/d/.virtualenvs/beplay/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 20, in __init__
    self.loader = MigrationLoader(self.connection)
  File "/home/d/.virtualenvs/beplay/local/lib/python2.7/site-packages/django/db/migrations/loader.py", line 52, in __init__
    self.build_graph()
  File "/home/d/.virtualenvs/beplay/local/lib/python2.7/site-packages/django/db/migrations/loader.py", line 274, in build_graph
    raise exc
django.db.migrations.exceptions.NodeNotFoundError: Migration places.0001_initial dependencies reference nonexistent parent node (u'cities', u'0010_adjust_unique_attributes')

然后我删除了那些依赖项,卸载了 django-cities ,这样一切就正常了,但是如果其他人需要安装该项目,则 migrate 命令会引发以下错误:

ValueError: Related model u'cities.Subregion' cannot be resolved

因为我从requirements.txt中删除了它,但它仍然在迁移0001_initial.py中被引用:

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Venue',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
                ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
                ('name', models.CharField(max_length=255)),
                ('phone', models.CharField(blank=True, max_length=255, null=True)),
                ('mobile', models.CharField(blank=True, max_length=255, null=True)),
                ('email', models.EmailField(blank=True, max_length=254, null=True)),
                ('address', models.CharField(blank=True, max_length=255, null=True)),
                ('latitude', models.CharField(blank=True, max_length=100, null=True)),
                ('longitude', models.CharField(blank=True, max_length=100, null=True)),
                ('subregion', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cities.Subregion')),
            ],
            options={
                'abstract': False,
            },
        ),
    ]

然后我删除了这行:

('subregion', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cities.Subregion')),

并且出现了另一个错误:

AttributeError: 'NoneType' object has no attribute 'is_relation'

我也试图从项目中删除所有 .pyc 文件,同时我谷歌了这个错误并找到了这个,但它没有给出答案。

有关此事的任何信息吗?

谢谢,对我的糟糕英语表示抱歉。


尝试删除此迁移文件,然后再运行makemigration和migrate,但首先从数据库中删除Venue表,并从django_migrations表中删除旧的venue迁移文件条目。 - Neeraj Kumar
我不想从数据库中删除Venue表。 - Diego Puente
1个回答

5

有两种可能的解决方案:

注意: 对于以下两种解决方案,您需要在继续之前从数据库中删除旧的Venue表。

简单的方法:

  • 进入您的migrations/文件夹并删除除__init__.py文件以外的所有内容。

  • INSTALLED_APPS中删除您的应用程序。

  • 运行python manage.py makemigrations,它将重新创建您的迁移文件夹中的迁移文件。

  • 运行python manage.py migrate

    缺点: 如果有所影响,您将失去迁移历史记录(在您的情况下,我假设这不重要,因为您引用了迁移0001

困难的方法:

您需要修改migrations/文件夹中的每个迁移文件:

  • Go to every migration file and find any reference to the app that will get uninstalled
  • Delete those references:

    Example delete the line:

    ('subregion', models.ForeignKey(
                      blank=True, 
                      null=True,
                      on_delete=django.db.models.deletion.CASCADE,
                      to='cities.Subregion'
                  ))
    

    from the Venue table fields migration.

  • Delete your app from the INSTALLED_APPS.

  • Run python manage.py migrate

    Drawbacks: It is complicated and prone to mistakes.


我认为简单的解决方案应该有效,但我必须确保所有服务器(staging和prod)都部署了最新的迁移,因为我必须从文件夹中删除所有迁移文件。然后当有人需要安装项目时,将会无知地通过。感谢您的编辑和回答。我会进行测试。 - Diego Puente
在简单的解决方案中,在执行makemigrations之后,您将获得一个新的0001_initial.py文件,此后您可以使用它! - John Moutafis
我在这里有疑问,因为django_migrations记录发生了什么?因为当我在这个应用程序中进行迁移时,Django将创建一个0002迁移,在staging和production数据库中已经应用了。 - Diego Puente
如果您无法在暂存和生产服务器上删除数据库,则无法解决问题:/。如果您想保留迁移记录,则需要遵循更困难的解决方案。 - John Moutafis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接