Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a custom function/method in sqlalchemy model to do CRUD operations?

Below I have a Flask-SQLAlchemy model for the table User.

class User(db.Model):
    __tablename__ = 'user'

    user_id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), nullable=False)
    created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP"))
    updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP"))

    def __init__(self):
        #self.name = name
        self.name = None

    def add_user(self, name):
        self.name = name

Here add_user is a custom method. So if I call the add_user method it should add the name to the User table.

Likewise how do I write custom methods for CRUD operations in that model itself?

like image 278
Kumaran Avatar asked Mar 05 '16 12:03

Kumaran


People also ask

What is __ repr __ SQLAlchemy?

The __repr__ function is defined by the designer of a type, in order to provide a means for users of the type to represent values of that type unambiguously, with a string.

What does all () do in SQLAlchemy?

all() method. The Query object, when asked to return full entities, will deduplicate entries based on primary key, meaning if the same primary key value would appear in the results more than once, only one object of that primary key would be present.

How do I create a SQLAlchemy query?

Python Flask and SQLAlchemy ORMAll SELECT statements generated by SQLAlchemy ORM are constructed by Query object. It provides a generative interface, hence successive calls return a new Query object, a copy of the former with additional criteria and options associated with it.


2 Answers

You'll probably want to use a classmethod to accomplish this.

class User(db.Model):
    __tablename__ = 'user'

    user_id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), nullable=False)
    created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP"))
    updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP"))

    def __init__(self, name):
        self.name = name

    @classmethod
    def create(cls, **kw):
        obj = cls(**kw)
        db.session.add(obj)
        db.session.commit()

This way you can use User.create(name="kumaran") to create a new user that will be committed to the database.

Better yet, it is a great idea to create a mixin for this method and others like it so that the functionality can be easily reused in your other models:

class BaseMixin(object):
    @classmethod
    def create(cls, **kw):
        obj = cls(**kw)
        db.session.add(obj)
        db.session.commit()

You can then reuse this functionality in your models by using multiple inheritance, like so:

class User(BaseMixin, db.Model):
    __tablename__ = 'user'

    user_id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), nullable=False)
    created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP"))
    updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP"))

    def __init__(self, name):
        self.name = name
like image 69
Patrick Allen Avatar answered Sep 18 '22 04:09

Patrick Allen


Not sure this is relevant to Flask-SQLAlchemy, but basic SQLAlchemy has examples of creating Mixin classes or augmenting the Base class.

https://docs.sqlalchemy.org/en/13/orm/extensions/declarative/mixins.html

e.g.

from sqlalchemy.ext.declarative import declared_attr

class MyMixin(object):

    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

    __table_args__ = {'mysql_engine': 'InnoDB'}
    __mapper_args__= {'always_refresh': True}

    id =  Column(Integer, primary_key=True)

class MyModel(MyMixin, Base):
    name = Column(String(1000))
like image 37
barakbd Avatar answered Sep 21 '22 04:09

barakbd