Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python/SQLModel; nice syntax to add a method call to `__init__` and `update`?

I’m experimenting with SQLModel as an ORM. A few of my models have custom validation, calculated fields, or just things that I want to happen when they’re created or changed. I end up using the following boilerplate a lot:

class MyModel(SqlModel):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.custom_method()

    def update(self, **kwargs):
        super().update(**kwargs)
        self.custom_method()

    def custom_method(self):
        """Do this when a model is created or updated
        """
        pass

Is there some nice way I can sweeten this syntax a little? Ideally I’d like a decorator around the function that would inject the function call into __init__ and update:

class MyModel(SqlModel):
    @run_on_change
    def custom_method(self):
        """Do this when a model is created or updated
        """
        pass

But I can’t figure out how this would work, since a decorator intercepts when a function is called and modifies its behaviour, whereas I want to modify the circumstances in which the function is called.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Alternatively, can anyone make a compelling argument for using a @listens_for decorator instead of the above boilerplate approach associated with the model itself?

>Solution :

Define an abstract base class to act as the bridge between SQLModel and your concrete subclasses.

from abc import ABC, abstractmethod


class MyBaseModel(SQLModel, ABC):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.custom_method()

    def update(self, **kwargs):
        super().update(**kwargs)
        self.custom_method()

    @abstractmethod
    def custom_method(self):
        pass


class MyModel(MyBaseModel):
    def custom_method(self):
        """Do stuff here"""
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading