Search code examples
pythonpydanticpolyfactory

Overriding nested values in polyfactory with pydantic models


Is it possible to provide values for complex types generated by polyfactory?

I use pydantic for models and pydantic ModelFactory. I noticed that build method supports kwargs that can provide values for constructed model, but I didn't figure if it's possible to provide values for nested fields.

For example, if I have model A which is also the type for field a in model B, is ti possible to construct B via polyfactory and provide some values for field 'a'?

I tried to call build with

MyFactory.build(**{"a": {"nested_value": "b"}})

but it does not work.

Is it possible to override nested values?


Solution

    • just add another Factory for 'b'
    • example code:
    from pydantic_factories import ModelFactory
    from datetime import date, datetime
    from typing import List, Union, Dict
    from pydantic import BaseModel, UUID4
    class B(BaseModel):
        k1: int
        k2: int
    
    class Person(BaseModel):
        id: UUID4
        name: str
        hobbies: List[str]
        age: Union[float, int]
        birthday: Union[datetime, date]
        nested_model: B
    
    class PersonFactory(ModelFactory):
        __model__ = Person
    
    class KFactory(ModelFactory):
        __model__ = B
    
    result = PersonFactory.build(**{"name" :"test","hobbies" : [1,2],"nested_model" : KFactory.build(k1=1,k2=2)})
    print(result)
    # same result
    result = PersonFactory.build(**{"name" :"test","hobbies" : [1,2],"nested_model" : KFactory.build(**{"k1":1,"k2":2})})
    print(result)
    
    • result:
    id=UUID('1ff7c9ed-223a-4f98-a95e-e3307426f54e') name='test' hobbies=['1', '2'] age=488202245.889748 birthday=datetime.date(2023, 3, 2) nested_model=B(k1=1, k2=2)