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)
}