factory_boy中的一对多关系

Nik*_*sMM 8 python sqlalchemy factory-boy

我使用SQLalchemy作为我的ORM,并试图将我的测试夹具移植到factory_boy.我的架构包括一对多关系中的两个对象.即一个模型的实例具有类似于具有另一个模型的结构的列表.例:

class Person(...):
  id = Column(Integer, primary_key=True)
  name = Column(Text)
  [...]

class Address(...):
  id = Column(Integer, primary_key=True)
  city = Column(Text)
  [...]
  person_id = Column(Integer, ForeignKey('person.id'))
  person = relationship("Person", backref="addresses")
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试创建一个工厂,创建具有几个地址的人.Factory_boy有SubFactory.但我只看到你如何在一对一的关系中使用它.我知道我可以用一个单独的工厂创建地址然后附加它们,但我想做像person =PersonFactory.create(num_addresses = 4)` 这样的事情.

有谁知道这在Factory_boy目前是否可行?

我使用factory_boy 2.4.1.

Sar*_*iev 7

我在我的项目中使用这种模式。假设您已经拥有AddressFactory.

https://factoryboy.readthedocs.io/en/latest/reference.html?highlight=post_generation#factory.post_generation

class PersonFactory(factory.alchemy.SQLAlchemyFactory):
    class Meta:
        model = Person

    @factory.post_generation
    def addresses(obj, create, extracted, **kwargs):
        if not create:
            return

        if extracted:
            assert isinstance(extracted, int)
            AddressFactory.create_batch(size=extracted, person_id=self.id, **kwargs)
Run Code Online (Sandbox Code Playgroud)

用法

PersonFactory(addresses=4)
Run Code Online (Sandbox Code Playgroud)

这将创建Person4 Addresses

这也可以接受 kwargs

PersonFactory(addresses=2, addresses__city='London')
Run Code Online (Sandbox Code Playgroud)

这将创建Person2 个Addresses,其city字段设置为'London'

这是可能有帮助的博客文章https://simpleit.rocks/python/django/setting-up-a-factory-for-one-to-many-relationships-in-factoryboy/


小智 -2

您可以使用此处描述的解决方案:http://factoryboy.readthedocs.org/en/latest/recipes.html#reverse-dependency-reverse-foreignkey

RelatedFactory基本上,只需在您的 上声明一些PersonFactory

class PersonFactory(factory.alchemy.SQLAlchemyFactory):
    class Meta:
        model = Person

    address_1 = factory.RelatedFactory(AddressFactory, 'person')
    address_2 = factory.RelatedFactory(AddressFactory, 'person')
Run Code Online (Sandbox Code Playgroud)