I’m new to using Pydantic and I’m using it to set up the models for FastAPI to integrate with my postgres database. I want to make a model that has an updated_at and created_at field which store the last datetime the model was updated and the datetime the model was created. I figured created_at could be something like this:
created_at: datetime = datetime.now()
How would I do an updated_at so it updates the datetime automatically every time the model is updated?
Advertisement
Answer
You can use a validator which will update the field updated_at
each time when some other data in the model will change. The root_validator and the validate_assignment config attribute are what you are looking for.
This is the sample code:
from datetime import datetime from time import sleep from pydantic import BaseModel,root_validator class Foo(BaseModel): data: str = "Some data" created_at: datetime = datetime.now() updated_at: datetime = datetime.now() class Config: validate_assignment = True @root_validator def number_validator(cls, values): values["updated_at"] = datetime.now() return values if __name__ == '__main__': bar = Foo() print(bar.dict()) sleep(5) bar.data = "New data" print(bar.dict())
and the output:
{ 'data': 'Some data', 'created_at': datetime.datetime(2022, 7, 31, 10, 41, 13, 176243), 'updated_at': datetime.datetime(2022, 7, 31, 10, 41, 13, 179253) } { 'data': 'New data', 'created_at': datetime.datetime(2022, 7, 31, 10, 41, 13, 176243), 'updated_at': datetime.datetime(2022, 7, 31, 10, 41, 18, 184983) }
You can see that there is a difference in microseconds after object creation. If this is a problem you can set:
updated_at: Optional[datetime] = None
and modify the validator like this:
@root_validator def number_validator(cls, values): if values["updated_at"]: values["updated_at"] = datetime.now() else: values["updated_at"] = values["created_at"] return values
and the new output:
{ 'data': 'Some data', 'created_at': datetime.datetime(2022, 7, 31, 10, 54, 33, 715379), 'updated_at': datetime.datetime(2022, 7, 31, 10, 54, 33, 715379) } { 'data': 'New data', 'created_at': datetime.datetime(2022, 7, 31, 10, 54, 33, 715379), 'updated_at': datetime.datetime(2022, 7, 31, 10, 54, 38, 728778) }