Support for generating the models with alias
alazaralemayehu opened this issue · 8 comments
Hello, thank you for your support. Is there a way to generate the pydantic fake models that contains aliases field.
For example,
class Person(Model): userName: str = Field(alias='user_name')
the current factory generates only using fieldName (userName), is it possible to create the generate models using alias name?
thank you.
Yes, there is a class variable for this. Checkout the docs.
did you find what you needed or is there an issue?
Hi, I'm trying to look for this as well. The ones I see on the docs are:
__model__ = Person
__faker__ = my_faker
__sync_persistence__ = SyncPersistenceHandler
__async_persistence__ = AsyncPersistenceHandler
__allow_none_optionals__ = False
They don't seem to be related? It looks like it's also missing docs for __random_seed__
.
Hi,
So currently there is a method on the factory that determines per field whether to use alias:
@classmethod
def _should_use_alias_name(cls, model_field: "ModelField", model: Type[T]) -> bool:
"""Determines whether a given model field should be set by an alias.
Args:
model_field: A 'ModelField' instance.
model: A model class.
Returns:
A boolean determining whether the field alias should be used.
"""
return bool(model_field.alias) and not (
issubclass(model, BaseModel) and model.__config__.allow_population_by_field_name
)
What are you guys looking for to have?
I was trying to look at that, but (model, BaseModel) and model.__config__.allow_population_by_field_name
is always true. I'm not sure if I'm missing any additional configs.
class Person(Model):
user_name: str = Field(alias='username')
class PersonFactory(ModelFactory):
__model__ = Person
x = PersonFactory.build() # I want it to be built with alias, so with `username` instead of `user_name`
Is that possible?
I was trying to look at that, but
(model, BaseModel) and model.__config__.allow_population_by_field_name
is always true. I'm not sure if I'm missing any additional configs.class Person(Model): user_name: str = Field(alias='username') class PersonFactory(ModelFactory): __model__ = Person x = PersonFactory.build() # I want it to be built with alias, so with `username` instead of `user_name`Is that possible?
You can pass a dict of values with username
. I will have to look into the other part.
I am sorry for touching a closed issue, but @Goldziher you closed this issue while the problem is still here and I do not see that this is documented
from pydantic import BaseModel, Field
from polyfactory.factories.pydantic_factory import ModelFactory
class Person(BaseModel):
id: int = Field(alias="_id")
class PersonFactory(ModelFactory[Person]):
__model__ = Person
person_instance = PersonFactory.build()
Error:
E pydantic_core._pydantic_core.ValidationError: 1 validation error for Person
E _id
E Field required [type=missing, input_value={}, input_type=dict]
E For further information visit https://errors.pydantic.dev/2.1/v/missing
.venv/lib/python3.11/site-packages/polyfactory/factories/pydantic_factory.py:334: ValidationError
Should I create a new issue?
UPDATE
Solved by populate_by_name
in the model itself. But this is a bad workaround because I need to modify the source code to make tests happy. Ugly workaround example:
from pydantic import BaseModel, ConfigDict, Field
from polyfactory.factories.pydantic_factory import ModelFactory
# Application code
class Person(BaseModel):
id: int = Field(alias="_id")
# Tests code
class PersonTest(Person):
model_config = ConfigDict(populate_by_name=True)
class PersonFactory(ModelFactory[PersonTest]):
__model__ = PersonTest
I am sorry for touching a closed issue, but @Goldziher you closed this issue while the problem is still here and I do not see that this is documented
from pydantic import BaseModel, Field from polyfactory.factories.pydantic_factory import ModelFactory class Person(BaseModel): id: int = Field(alias="_id") class PersonFactory(ModelFactory[Person]): __model__ = Person person_instance = PersonFactory.build()Error:
E pydantic_core._pydantic_core.ValidationError: 1 validation error for Person E _id E Field required [type=missing, input_value={}, input_type=dict] E For further information visit https://errors.pydantic.dev/2.1/v/missing .venv/lib/python3.11/site-packages/polyfactory/factories/pydantic_factory.py:334: ValidationError
Should I create a new issue?
UPDATE
Solved by
populate_by_name
in the model itself. But this is a bad workaround because I need to modify the source code to make tests happy. Ugly workaround example:from pydantic import BaseModel, ConfigDict, Field from polyfactory.factories.pydantic_factory import ModelFactory # Application code class Person(BaseModel): id: int = Field(alias="_id") # Tests code class PersonTest(Person): model_config = ConfigDict(populate_by_name=True) class PersonFactory(ModelFactory[PersonTest]): __model__ = PersonTest
You're welcome to create a bug report with a reproduction