How to deal with a `relation "cms_disclaimerpanel" already exists` and ProgrammingError: column "http_request_lang" of relation "xyz" does not exist

How to deal with a `relation "cms_disclaimerpanel" already exists` and ProgrammingError: column "http_request_lang" of relation "xyz" does not exist

在 circle CI.

上尝试将我的合并发送到我的自动化测试时,我遇到了一个相当烦人的问题

仅供参考,我继承了一个项目,作者不再从事我目前的工作。

我正在开发 django,我已经完成了从本地开发 b运行ch 到本地主 b运行ch 的合并。合并进行得很顺利。但是,当通过 manage.py runserver 启动 django 服务器时,它会给我警告 Your project may not work properly until you apply the migrations for app(s)[...].

在做 manage.py migrate 时,我 运行 正在进入第一期:

1- django.db.utils.ProgrammingError: relation "cms_disclaimerpanel" already exists

我通过手动编辑迁移文件解决了这个问题,评论了以下行

 #       migrations.CreateModel(
 #           name='DisclaimerPanel',
 #           fields=[
 #               ('abstractpanel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.AbstractPanel')),
 #               ('title', models.CharField(blank=True, max_length=1024, verbose_name='title')),
 #               ('show_title', models.BooleanField(default=True, verbose_name='show title')),
 #               ('subtitle', models.TextField(blank=True, verbose_name='content')),
 #               ('show_subtitle', models.BooleanField(default=True, verbose_name='show subtitle')),
 #               ('alignment', models.CharField(choices=[('left', 'left'), ('center', 'center')], default='center', max_length=10, verbose_name='text alignment')),
 #               ('button', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cms.Link')),
 #           ],
 #           options={
 #               'verbose_name': 'Disclaimer Panel',
 #           },
 #           bases=('cms.abstractpanel',),
 #       )

然后第二个问题发生了,带着我的manage.py migrate

2 - ProgrammingError: column "http_request_lang" of relation "cms_dynamicsettings" does not exist

我通过手动编辑迁移文件解决了这个问题,评论了以下行

#operations = [
#    migrations.RemoveField(
#        model_name='dynamicsettings',
#        name='http_request_lang',
#    ),
#]

manage.py 能够 运行 完全。然后我 运行 manage.py makemigrations 它给了我最后一个文件

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        ('cms', '0088_merge_20190411_1655'),
    ]

    operations = [
        migrations.CreateModel(
            name='DisclaimerPanel',
            fields=[
                ('abstractpanel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cms.AbstractPanel')),
                ('title', models.CharField(blank=True, max_length=1024, verbose_name='title')),
                ('show_title', models.BooleanField(default=True, verbose_name='show title')),
                ('subtitle', models.TextField(blank=True, verbose_name='content')),
                ('show_subtitle', models.BooleanField(default=True, verbose_name='show subtitle')),
                ('alignment', models.CharField(choices=[('left', 'left'), ('center', 'center')], default='center', max_length=10, verbose_name='text alignment')),
                ('button', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cms.Link')),
            ],
            options={
                'verbose_name': 'Disclaimer Panel',
            },
            bases=('cms.abstractpanel',),
        ),
        migrations.RemoveField(
            model_name='dynamicsettings',
            name='http_request_lang',
        ),
    ]

通过以上修改,我可以运行manage.py runserver.

然后我将这 3 个文件添加到我合并的 b运行ch 并为我的 b运行ch 创建一个远程存储库。

每个新创建的存储库 运行 通过单元测试,问题就出在这里,因为它没有考虑我新提交的三个文件。

它给了我以下错误,与第 2 点中的错误相同(见上文)。

ERROR:  relation "cms_dynamicsettings" does not exist at character 1508

使用我的开发环境作为模板,我的猜测是 circle ci 正在复制我遇到的相同问题并且我手动修复了。

问题如下:

再补充一个信息:

数据库是用b运行ch master建的。我在另一个基于 master 的 b运行ch 上结帐,将我的开发 b运行ch 合并到 master 中,然后执行 manage.py migrate.

任何信息都将非常受欢迎,因为我正在失去理智。

谢谢。

这种情况下的程序是确保您首先进入与数据库同步的状态(假设您不能删除数据库,因为系统正在生产中)。

  1. 检查您的生产数据库 table "django_migrations" 并查看为您的每个应用程序应用的最后一次迁移。
  2. 在您的代码中,删除在上次迁移之后添加的所有迁移文件。为每个应用程序执行此操作。确保应用到数据库的所有迁移文件都存在于代码库中。
  3. 运行 manage.py migrate,如果您的迁移文件与您的数据库同步,它应该什么都不做("nothing to migrate")。
  4. 运行 manage.py makemigrations 这将创建一个额外的迁移文件,以反映模型中相对于数据库的所有更改。
  5. 运行 manage.py migrate 现在应该一切正常了。

执行此操作时需要担心的一些事情:

  • 确保您正在使用的所有数据库(在所有环境中)都与生产数据库同步。
  • 确保没有人在可能存在其他迁移的不同分支上工作。