Django事务测试用例在sqlite数据迁移时引发IntegrityError

3 投票
3 回答
1379 浏览
提问于 2025-04-28 05:39

我正在尝试把一个使用 LiveServerTestCase 的 Django 1.6 项目迁移到 Django 1.7。为了这个迁移,我把初始数据的设置转换成了数据迁移。但是这样一来,我的所有实时服务器测试都失败了,因为数据被清空了。后来我发现了 TransactionTestCase 的 serialized_rollback 选项,并把它加到了我的测试类中。不过现在,当我运行测试时,出现了以下错误:

sqlite3.IntegrityError: UNIQUE constraint failed: django_content_type.app_label, django_content_type.model

我在这里的一个示例应用中复现了这个问题: https://github.com/tctimmeh/djangomigrate

模型:

class SomeData(Model):
    value = IntegerField()

数据迁移:

def createData(apps, schema_editor):
    SomeData = apps.get_model('mtestapp', 'SomeData')
    db_alias = schema_editor.connection.alias
    SomeData.objects.using(db_alias).bulk_create([
        SomeData(value = 1),
    ])

class Migration(migrations.Migration):
    dependencies = [
        ('mtestapp', '0001_initial'),
    ]
    operations = [
        RunPython(createData)
    ]

还有测试:

class TestIt(TransactionTestCase):
    serialized_rollback = True
    def test_one(self):
        self.assertEqual(1, SomeData.objects.all().count())
    def test_two(self):
        self.assertEqual(1, SomeData.objects.all().count())

其中一个测试通过了,另一个则引发了上面提到的 IntegrityError。你知道这可能是什么原因吗?

编辑:我进一步研究了一下,发现 django.contrib.contenttypes 应用有一个在测试数据库被清空后运行的 post_migrate 管理命令。有没有办法阻止这个命令运行呢?

暂无标签

3 个回答

0

你需要将你的应用程序添加到 available_apps 中,这样Django就会像只使用这个应用里的模型一样。在你的测试案例中,你可以这样做:

class TestIt(TransactionTestCase):
  serialized_rollback = True
  available_apps = ['mtestapp']

  def test_one(self):
    self.assertTrue(True)

  def test_two(self):
    self.assertTrue(True)
0

我在不同的情况下遇到了同样的问题。 我把 serialized_rollback = True 去掉了,然后在 setUp() 方法里手动添加了一些测试数据。

0

这个问题在Django 1.9版本中已经修复了:https://code.djangoproject.com/ticket/23727

在更早的版本中,我通过在每次测试之前重新创建我的静态数据来解决这个问题。

撰写回答