Skip to content

__init_subclass__ not working as expected with SQLModel #395

@LCBerndsen

Description

@LCBerndsen

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the SQLModel documentation, with the integrated search.
  • I already searched in Google "How to X in SQLModel" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to SQLModel but to Pydantic.
  • I already checked if it is not related to SQLModel but to SQLAlchemy.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

#WORKING EXAMPLE
from pydantic import BaseModel, root_validator, ValidationError

class Philosopher(BaseModel):
    def __init_subclass__(cls, default_name=None, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

    @root_validator(pre=True)
    def default_name_validator(cls, values):
        print(cls.default_name)
        if values["name"] != cls.default_name:
            raise ValidationError("name not correct")
        return values


class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    name: str


class GermanPhilosopher(Philosopher, default_name="Nietzsche"):
    name: str


Bruce = AustralianPhilosopher(name="Bruce")
Nietzsche = GermanPhilosopher(name="Nietzsche")
Error = GermanPhilosopher(name="test")

# DESIRED:
class Philosopher(SQLModel):
    def __init_subclass__(cls, default_name=None, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

    @root_validator(pre=True)
    def default_name_validator(cls, values):
        print(cls.default_name) # -> Now this is None
        if values["name"] != cls.default_name:
            raise ValidationError("name not correct")
        return values


class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    name: str


class GermanPhilosopher(Philosopher, default_name="Nietzsche"):
    name: str


Bruce = AustralianPhilosopher(name="Bruce")
Nietzsche = GermanPhilosopher(name="Nietzsche")
Error = GermanPhilosopher(name="test")

Description

Building forward from this Stackoverflow issue, I create a base class that has a __init_subclass__ method. In this baseclass, I want to have a root_validator for all classes that subclass this baseclass. This seems to work when I have pydantic's BaseModel as the Base for my Philosopher class, but my actual goal is to do this with SQLModel's Base. If I do so, the default_name attribute of cls is None.

.

Operating System

macOS

Operating System Details

No response

SQLModel Version

sqlmodel = "0.0.6"

Python Version

3.10.3

Additional Context

Workaround
I could do a dirty fix by setting title = "Bruce" and title ="Nietzsche" instead of default_name. Because then I would be able to call it using cls.config.title but that does not seem like a responsible fix


class Philosopher(SQLModel):
    def __init_subclass__(cls, default_name=None, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

    @root_validator(pre=True)
    def default_name_validator(cls, values):
        print(cls.__config__.title)
        if values["name"] != cls.__config__.title:
            raise ValidationError("name not correct")
        return values


class AustralianPhilosopher(Philosopher, title="Bruce"):
    name: str


class GermanPhilosopher(Philosopher, title="Nietzsche"):
    name: str


Bruce = AustralianPhilosopher(name="Bruce")
Nietzsche = GermanPhilosopher(name="Nietzsche")
Error = GermanPhilosopher(name="test")

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions