You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django单元测试:数据库行ID固定问题及查询报错解决方案咨询

Django单元测试中ID查询失败的原因与解决方法

你的判断是错误的:Django的TestCase会创建真实的测试数据库,setUp里的save()操作确实会把数据插入到数据库中,并非“未执行真实插入”。出现UserType.DoesNotExist错误的核心原因是数据库自增序列不会随事务回滚重置——Django测试用事务隔离每个测试方法,测试结束后会回滚插入的数据,但PostgreSQL、MySQL这类数据库的自增ID序列不会回滚,若测试类中有其他测试方法先执行过插入操作,哪怕数据被回滚,下一次插入的ID会延续之前的序列值,导致你预期的ID=1失效。

解决方法

1. 避免依赖固定ID(推荐最佳实践)

不要硬编码ID进行查询,而是在setUp中将创建的实例保存为测试类的属性,后续测试方法直接引用:

from django.test import TestCase

class DefTests(TestCase):
    def setUp(self): 
        # 将实例保存为类属性
        self.user_type = UserType.objects.create(label="mylabel")

    def test_my(self):
        # 直接通过实例属性查询或使用
        u = UserType.objects.get(id=self.user_type.id)
        # 更简洁的方式:直接使用已保存的实例,无需重新查询
        # u = self.user_type

2. 显式指定ID

创建实例时强制设置id字段,跳过数据库自增序列的自动分配:

from django.test import TestCase

class DefTests(TestCase):
    def setUp(self): 
        # 强制设置id为1
        UserType(id=1, label="mylabel").save()

    def test_my(self):
        u = UserType.objects.get(id=1)  # 此时查询可正常获取数据

3. 重置数据库自增序列(仅特殊场景使用)

如果必须依赖自增序列从1开始,可以在setUp中执行原生SQL重置序列,不同数据库语法不同:

  • 针对MySQL:
from django.test import TestCase
from django.db import connection

class DefTests(TestCase):
    def setUp(self): 
        with connection.cursor() as cursor:
            # 替换yourapp_usertype为你的模型对应的数据库表名
            cursor.execute("ALTER TABLE yourapp_usertype AUTO_INCREMENT=1;")
        UserType(label="mylabel").save()

    def test_my(self):
        u = UserType.objects.get(id=1)
  • 针对PostgreSQL:
from django.test import TestCase
from django.db import connection

class DefTests(TestCase):
    def setUp(self): 
        with connection.cursor() as cursor:
            # 替换yourapp_usertype_id_seq为你的模型ID对应的序列名(通常为表名_id_seq)
            cursor.execute("SELECT setval('yourapp_usertype_id_seq', 1, false);")
        UserType(label="mylabel").save()

    def test_my(self):
        u = UserType.objects.get(id=1)

内容的提问来源于stack exchange,提问作者whitebear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:22:11