为什么迁移在测试时失败,而在迁移时失败?

时间:2014-09-24 01:19:12

标签: django-testing django-1.7 django-migrations

我正在使用Django == 1.7,并且有四个应用程序:

frontend
game
geo
people

应用设置如下:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'fandjango',
    'people',
    'geo',
    'game',
    'frontend'
)

数据库设置为:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'hoods_raising',
        'USER': 'hoods_raising',
        'PASSWORD': 'hr$nestor$123',
        'HOST': 'localhost',
        'TEST_CHARSET': 'utf8mb4'
    }
}

我的应用程序有迁移和测试:

game
    migrations
        0001_initial.py
geo
    migrations
        0001_initial.py
    tests.py
people
    migrations
        0001_initial.py
        0002_install_data.py

省略了许多文件以缩小问题范围(如果需要,我会用更多文件扩展问题),例如models.pyviews.py

0002_install_data.py的内容是:

class Migration(migrations.Migration):

    dependencies = [
        ('people', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(NamesInstaller(), lambda apps, schema_editor: None)
    ]

如果我运行manage.py migrate来安装数据库,一切都按预期工作。

如果我运行manage.py test来运行测试,第一步将是测试数据库安装。奇怪的事情发生了:

  • 要执行的第一个迁移是0002_install_data。永远不会创建其他表(例如,auth表,地理表,游戏表,fandjango表......),并且people中的迁移0001_initial未运行。
  • 由于这个原因0002_install_data中出现依赖性错误(它表示0001_initial不存在)。

    KeyError: u"Migration people.0002_install_data dependencies references nonexistent parent node (u'people', u'0001_initial')"
    

为什么会发生这种情况?为什么test命令不能正确安排应用程序迁移? (发生在manage.py migrate)。

1 个答案:

答案 0 :(得分:3)

我解决了。出现这个问题是因为我搞砸了Squashed迁移:因为我事先没有将它部署到一个高效的环境中,所以我可以自由删除被替换的迁移(并且只保留被压缩的)。

当您删除已替换的迁移并保持被压缩然后进行迁移时,一切都将按预期工作。但是,如果您运行replaced,则压缩的迁移将引用tests迁移,因此会失败。

不幸的是,我将被压缩的迁移命名为0001_initial,就像第一次迁移一样,误导我认为这是一个存在文件的依赖性问题。

所以:如果你想压缩迁移确保你知道你正在做什么并且不删除以前的迁移,除非:

  • 你知道没有人会再次使用它们(即没有实例在被压扁的迁移路径的“中间”)。
  • 您在压缩迁移中删除替换指令。否则测试将失败,因为数据库将无法设置。