Monday 27 September 2021

Pydantic: Create a model dynamically

‘create_model’ method is used to create models at runtime.

 

Example

EmployeeModel = create_model('EmployeeModel', id=(int,...), name=(str,...))

 

Find the below working application.

 

dynamic_model_1.py

 

from pydantic import BaseModel, create_model

EmployeeModel = create_model('EmployeeModel', id=(int,...), name=(str,...))

emp1 = EmployeeModel(id=1, name='Krishna')

print(EmployeeModel.__fields__.keys())
print('emp1 -> ' + emp1.json())

 

Output

dict_keys(['id', 'name'])
emp1 -> {"id": 1, "name": "Krishna"}

 

Can I extend another model?

Yes, Using __base__, you can specify the super class to this model.

 

Example

 

EmployeeModel = create_model(
    'EmployeeModel', 
    id=(int,...), 
    name=(str,...),
    org = 'ABC Corporation',
    __base__=Address
    )

Find the below working application.

 

dynamic_model_2.py

from pydantic import BaseModel, create_model

class Address(BaseModel):
    street: str = None
    city: str = None
    country: str = None

EmployeeModel = create_model(
    'EmployeeModel', 
    id=(int,...), 
    name=(str,...),
    org = 'ABC Corporation',
    __base__=Address
    )

emp1 = EmployeeModel(id=1, name='Krishna', street='Chowdeswari', city='Bangalore')

print(EmployeeModel.__fields__.keys())
print('emp1 -> ' + emp1.json())


Output

dict_keys(['street', 'city', 'country', 'id', 'name', 'org'])
emp1 -> {"street": "Chowdeswari", "city": "Bangalore", "country": null, "id": 1, "name": "Krishna", "org": "ABC Corporation"}


Can I add validators to a dynamic model?

Yes, by supplying ‘__validators__’ argument to the create_model, you can specify custom validators.

 

Step 1: Define validators.

def name_alphanumeric(cls, v):
    assert v.isalnum(), 'must be alphanumeric'
    return v

def age_is_greater_18(cls, v):
    assert v > 18, 'Age must be > 18'
    return v

validators = {
    'username_validator': validator('name')(name_alphanumeric),
    'userage_validator': validator('age')(age_is_greater_18)
}


Step 2: Specify validators using __validators__ argument.

EmployeeModel = create_model(
    'EmployeeModel', 
    id=(int,...), 
    name=(str,...),
    org = 'ABC Corporation',
    age=(int,...),
    __validators__=validators
    )


Find the below working application.

 

dynamic_model_3.py

from pydantic import BaseModel, create_model, validator, ValidationError

def name_alphanumeric(cls, v):
    assert v.isalnum(), 'must be alphanumeric'
    return v

def age_is_greater_18(cls, v):
    assert v > 18, 'Age must be > 18'
    return v

validators = {
    'username_validator': validator('name')(name_alphanumeric),
    'userage_validator': validator('age')(age_is_greater_18)
}

EmployeeModel = create_model(
    'EmployeeModel', 
    id=(int,...), 
    name=(str,...),
    org = 'ABC Corporation',
    age=(int,...),
    __validators__=validators
    )

try:
    emp1 = EmployeeModel(id=1, name='Krishna!@', street='Chowdeswari', city='Bangalore', age=15)
except ValidationError as e:
    print(e.json())


Output

[
  {
    "loc": [
      "name"
    ],
    "msg": "must be alphanumeric",
    "type": "assertion_error"
  },
  {
    "loc": [
      "age"
    ],
    "msg": "Age must be > 18",
    "type": "assertion_error"
  }
]

 

  

Previous                                                    Next                                                    Home

No comments:

Post a Comment