Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create subclasses with pydantic where each subclass instance have their own uuid?

I'm trying to create subclasses of Foo, where each should have its own uuid. In the real code no instance of Foo will be created, only its subclasses. The subclass instances will be saved in a database later, so the uuid is to retrieve the right objects from the database.

In the first code snippet, I tried to use the init method, which results in an AttributeError. I also tried to use a classmethod, which results in losing all the fields in my subclass objects.

If I use the second snippet, every subclass instance gets the same uuid, which makes sense to me, as it's passed as default value.

I could put the uuid creation into the subclass, though this feels wrong when using inheritance.

Is there a better way to create a uuid for each subclass instance?

# foo_init_.py
class Foo(BaseModel):
    def __init__(self):
          self.id_ = uuid4()
# >>> AttributeError: __fields_set__

# foo_classmethod.py
class Foo(BaseModel):
    @classmethod
    def __init__(cls):
          cls.id_ = uuid4()
# >>> Bar loses id_ fields

from uuid import uuid4, UUID
from pydantic import BaseModel


class Foo(BaseModel):
    id_: UUID = uuid4()


class Bar(Foo):
    pass


class Spam(Foo):
    pass


if __name__ == '__main__':
    b1 = Bar()
    print(b1.id_)  # >>> 73860f46-5606-4912-95d3-4abaa6e1fd2c
    b2 = Bar()
    print(b2.id_)  # >>> 73860f46-5606-4912-95d3-4abaa6e1fd2c
    s1 = Spam()
    print(s1.id_)  # >>> 73860f46-5606-4912-95d3-4abaa6e1fd2c

like image 452
J B Avatar asked Dec 07 '25 05:12

J B


1 Answers

You could use the default_factory parameter:

class Foo(BaseModel):
    id_: UUID = Field(default_factory=uuid4)
like image 95
alex_noname Avatar answered Dec 09 '25 02:12

alex_noname