Pydantic: dataclass vs BaseModel

Question:

What are the advantages and disadvantages of using Pydantic’s dataclass vs BaseModel? Are there any performance issues or is it easier to Pydantic’s dataclass in the other python module?

Asked By: sacherus

||

Answers:

Your question is answered in Pydantic’s documentation, specifically:

Keep in mind that pydantic.dataclasses.dataclass is a drop-in replacement for dataclasses.dataclass with validation, not a replacement for pydantic.BaseModel (with a small difference in how initialization hooks work). There are cases where subclassing pydantic.BaseModel is the better choice.

For more information and discussion see samuelcolvin/pydantic#710.

The discussion link will give you some of the context you are looking for. In general, Pydantic’s BaseModel implementation is not bound to behave the same as Python’s dataclass implementation. The example cited in the issue above is one good example:

from pydantic import BaseModel
from pydantic.dataclasses import dataclass
from typing import List

@dataclass
class A:
    x: List[int] = []

# Above definition with a default of `[]` will result in:
#   ValueError: mutable default <class 'list'> for field x is not allowed: use default_factory
# If you resolve this, the output will read as in the comments below.

class B(BaseModel):
    x: List[int] = []

print(A(x=[1, 2]), A(x=[3, 4])) # Output: A(x=[1, 2]) A(x=[3, 4])
print(B(x=[1, 2]), B(x=[3, 4])) # Output: x=[1, 2] x=[3, 4]

If what you want first and foremost is dataclass behavior and then to simply augment it with some Pydantic validation features, the pydantic.dataclasses.dataclass approach may be what you want. Otherwise, BaseModel is probably what you want.

Answered By: Jeffrey Wilges

The __repr__ string representation function for BaseModel is different from that of dataclass:

    @dataclass()
    class Foo:
        number: int
    
    class Bar(BaseModel):
        number: int
    
    f = Foo(number = 1.4)
    b = Bar(number = 1.4)
    print(f)
    print(b)

Output:

Foo(number=1.4)
number=1
Answered By: Phil997

Another option is to use openapi-json-schema-generator with model generation only. It allows robust validation of many python data types against openapi/json schemas. It

Answered By: spacether
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.