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

如何让FactoryBoy不为非托管Django模型生成id属性?

解决方案

1. 修正Django模型定义

你的非托管模型Person未显式指定主键,Django会自动添加默认的id字段,但数据库视图v_person不存在这个列,导致查询报错。需要给personality_id字段添加primary_key=True,让Django不再自动生成id字段:

class Person(models.Model):
    # 显式指定主键,避免Django自动添加id字段
    personality_id = models.IntegerField(db_column="personalityID", primary_key=True)
    state_id = models.IntegerField(db_column="stateID")
    first_name = models.CharField(db_column="firstName", max_length=35)
    last_name = models.CharField(db_column="lastName", max_length=40)
    middle_name = models.CharField(db_column="middleName", max_length=30)
    number = models.IntegerField(db_column="studentNumber")
    active_year = models.IntegerField(db_column="activeYear")
    birth_date = models.DateField(db_column="BirthDate")
    start_date = models.DateField(db_column="startDate")
    end_date = models.DateField(db_column="endDate", null=True)
    end_year = models.IntegerField(db_column="endYear")
    gender = models.CharField(db_column="gender", max_length=1)
    native_lang = models.CharField(db_column="languageAlt", max_length=5)

    class Meta(object):
        managed = False
        db_table = "v_person"

2. 调整FactoryBoy的实例生成策略

如果你的需求只是生成数据实例而非写入数据库,将PersonFactory.create()改为PersonFactory.build(),这样FactoryBoy不会触发数据库的get_or_create操作,也就不会产生查询id列的SQL:

修改RatedPersonalityFactory中的post_generation方法:

@post_generation
def person(obj, create, extracted, **kwargs):
    # 使用build()替代create(),仅生成内存中的模型实例
    PersonFactory.build(
        personality=obj,
        personality_id=obj.id,
        state_id=1234,
        first_name=obj.identity.first_name,
        last_name=obj.identity.last_name,
        middle_name=obj.identity.middle_name,
        birth_date=obj.identity.birth_date,
        number=obj.student_number,
        end_year=kwargs["end_year"],
    )

3. 可选:如果必须写入数据库

若需要将数据写入数据库(非托管模型通常不需要,但如果有特殊需求),确保PersonFactory的Meta配置正确,且模型主键与数据库视图匹配:

class PersonFactory(DjangoModelFactory):
    class Meta:
        model = Person
        database = "alternatives"
        # 基于显式主键字段进行get_or_create
        django_get_or_create = ("personality_id",)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:47:50