不为非托管Django模型生成'id'的FactoryBoy工厂?

v440hwme  于 2023-03-09  发布在  Go
关注(0)|答案(1)|浏览(108)

我有一个工厂,我只需要生成我想要的数据-***没有***让它创建一个'id'属性。
我有几个工厂看起来像这样:

class RatedPersonalityFactory(PersonalityFactory):
    person__end_year = get_end_year()
    rating_information__create_rating = False
    rating_information__section = None

    class Params:
        pass

    @post_generation
    def person(obj, create, extracted, **kwargs):
        PersonFactory(
            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"],
        )


class PersonFactory(DjangoModelFactory):
    class Meta:
        model = Person
        database = "alternatives"
        django_get_or_create = ("personality_id",)

    class Params:
        # This will create the Personality that we can then use attributes from
        personality = SubFactory(PersonalityFactory)
        current_end_year = get_end_year()

    personality_id = SelfAttribute("personality.id")
    state_id = 1234
    first_name = Faker("first_name")
    last_name = Faker("last_name")
    middle_name = Faker("first_name")
    number = SelfAttribute("person.student_number")
    active_year = 1
    birth_date = Faker(
        "date_between",
        start_date=(datetime.now() - relativedelta(years=14)).date(),
        end_date=datetime.now().date(),
    )
    start_date = Faker(
        "date_time_between",
        start_date="-1y",
        end_date="now",
        tzinfo=py_timezone(settings.TIME_ZONE),
    )
    end_date = None
    end_year = LazyFunction(get_end_year)
    gender = Iterator(["M", "F"])
    native_lang = "EN"

模型如下所示:

class Person(models.Model):
    personality_id = models.IntegerField(db_column="personalityID")
    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"

我看到以下错误:

File "/projects/project/tests/utils/factories.py", line 70, in person
    PersonFactory(
  File "/projects/project/venv/lib/python3.10/site-packages/factory/base.py", line 40, in __call__
    return cls.create(**kwargs)
  File "/projects/project/venv/lib/python3.10/site-packages/factory/base.py", line 528, in create
    return cls._generate(enums.CREATE_STRATEGY, kwargs)
  File "/projects/project/venv/lib/python3.10/site-packages/factory/django.py", line 117, in _generate
    return super()._generate(strategy, params)
  File "/projects/project/venv/lib/python3.10/site-packages/factory/base.py", line 465, in _generate
    return step.build()
  File "/projects/project/venv/lib/python3.10/site-packages/factory/builder.py", line 262, in build
    instance = self.factory_meta.instantiate(
  File "/projects/project/venv/lib/python3.10/site-packages/factory/base.py", line 317, in instantiate
    return self.factory._create(model, *args, **kwargs)
  File "/projects/project/venv/lib/python3.10/site-packages/factory/django.py", line 163, in _create
    return cls._get_or_create(model_class, *args, **kwargs)
  File "/projects/project/venv/lib/python3.10/site-packages/factory/django.py", line 140, in _get_or_create
    instance, _created = manager.get_or_create(*args, **key_fields)
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/models/query.py", line 581, in get_or_create
    return self.get(**kwargs), False
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/models/query.py", line 431, in get
    num = len(clone)
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/models/query.py", line 262, in __len__
    self._fetch_all()
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/models/query.py", line 1324, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/models/query.py", line 51, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1175, in execute_sql
    cursor.execute(sql, params)
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 79, in _execute
    with self.db.wrap_database_errors:
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/projects/project/venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/projects/project/venv/lib/python3.10/site-packages/mssql/base.py", line 619, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: ('42S22', "[42S22] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name 'id'. (207) (SQLExecDirectW)")

错误是由RatedPersonalityFactory上的@post_generation方法生成的。
这是一个非托管模型,因此表已经存在-我只需要FactoryBoy用数据填充表。
有什么想法吗?
我尝试将exclude = ("id",)添加到PersonFactory,但问题仍然存在。

kq0g1dla

kq0g1dla1#

您是否在测试数据库上创建了表?由于它不是托管的,因此创建它时不会进行迁移。这意味着您需要为测试数据库处理它的创建。
您还可以遵循this blog,它建议切换到managed=True进行测试

相关问题