如何对Django数据库迁移进行单元测试?

5 浏览
0 Comments

如何对Django数据库迁移进行单元测试?

我们已经使用django迁移(django v1.7+)更改了我们的数据库。\n数据库中存在的数据已经无效。\n基本上,我想通过在单元测试中构建预迁移数据库,添加一些数据,应用迁移,然后确认一切顺利进行来测试迁移。\n如何做到:\n

    \n

  1. 在加载单元测试时保留新迁移\n我在这里找到了一些关于覆盖settings.MIGRATION_MODULES的内容,但是我不知道如何使用。当我检查executor.loader.applied_migrations时,它仍然列出了所有内容。我唯一能够阻止新迁移的方法是实际上删除文件;这不是我能使用的解决方案。
  2. \n

  3. 在单元测试数据库中创建一条记录(使用旧模型)\n如果我们可以阻止迁移,那么这应该很简单。myModel.object.create(...)
  4. \n

  5. 应用迁移\n我想现在我可能可以解决这个问题,因为我找到了test_executor:设置一个指向迁移文件的计划并执行它?嗯,对吧?你有相关的代码吗?:-D
  6. \n

  7. 确认数据库中的旧数据与新模型匹配\n同样,我认为这应该很容易:只需获取迁移前创建的实例并确认它已按照正确的方式进行了更改。
  8. \n

\n所以挑战实际上就是弄清楚如何阻止单元测试应用最新的迁移脚本,然后在我们准备好时应用它?\n


\n也许我有错误的方法?我应该创建fixture,并在最后确认它们都正确吗?fixture是在应用迁移之前加载还是在所有迁移完成之后加载?\n


\n通过使用MigrationExecutor和使用.migrate选择特定的迁移,我已经可以,也许?将其回滚到特定的状态,然后逐个向前推进。但这引起了疑问;目前正在追踪sqlite的困扰,因为实际上没有ALTER TABLE指令。仍有疑问。

0
0 Comments

如何对Django数据库迁移进行单元测试?

最近,我们使用以下代码在`settings_test.py`中忽略了测试的迁移:

MIGRATION_MODULES = dict(
    (app.split('.')[-1], '.'.join([app, 'nonexistent_django_migrations_module']))
    for app in INSTALLED_APPS
)

这个想法是所有的应用都没有`nonexistent_django_migrations_module`文件夹,因此Django将找不到任何迁移。

谢谢。这确保了Django找不到任何迁移,但是似乎并没有多大帮助;如果找不到迁移,我们如何测试迁移?

显然,我误解了你的问题-你实际上想要测试迁移逻辑本身?

是的...一个测试,它创建一个迁移前的数据库,执行迁移,然后测试结果。

明白了。我认为修改标题以反映这一点将会很有帮助:)

解决方法:

- 首先,确保你的测试用例中包含了`django.test.TestCase`。

- 创建一个继承自`django.test.TestCase`的测试类。

- 在测试类中,使用`@classmethod`修饰符和`setUpClass`方法创建一个迁移前的数据库。

- 在`setUpClass`方法中,使用`django.core.management.call_command`命令来执行迁移。

- 在测试方法中,编写测试逻辑来验证迁移的结果。

下面是一个示例代码:

from django.test import TestCase
from django.core.management import call_command
class MigrationTestCase(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        # 创建迁移前的数据库
        call_command('migrate', 'your_app_name', 'zero')
    def test_migration_logic(self):
        # 编写测试逻辑来验证迁移的结果
        pass

通过这种方式,你可以测试迁移的逻辑,确保数据库迁移正常工作。

希望以上内容对你有所帮助!

0
0 Comments

问题的出现原因:作者在进行Django数据库迁移的单元测试时,希望能够在测试之前将数据库恢复到旧的状态,以便测试迁移过程。作者尝试了一些方法,最终找到了通过回滚到迁移历史中的旧版本来实现这一目的的方法。

解决方法:作者发现可以通过以下步骤将数据库恢复到旧的状态:

1. 使用MigrationExecutor来执行迁移历史中的旧版本:executor.migrate([("workflow_engine", "0014_nulls_permitted")])

2. 在每次执行executor.migrate之间运行executor.loader.build_graph方法,以确保完成迁移并使数据库行为符合预期。

3. 可以使用executor.loader.applied_migrations方法来检查当前适用于数据库的迁移版本。

4. 可以通过直接运行SQL语句来确保数据库处于旧的状态,例如:cursor.execute('UPDATE workflow_engine_job SET next_job_state=NULL')

5. 接下来,可以运行executor.migrate([("workflow_engine", "0016_nulls_banished")])来进行迁移。

6. 最后,可以通过编写测试来确认迁移是否成功,例如通过检查数据库中是否还有NULL值:self.assertTrue(all([j.next_job_state is not None for j in jobs]))

以上就是作者在进行Django数据库迁移的单元测试时遇到的问题以及解决方法。通过将数据库恢复到旧的状态,作者可以测试迁移过程并确保其正确性。

0