web-dev-qa-db-ja.com

CRUD操作を行うためにsqlalchemyモデルにカスタム関数/メソッドを追加するにはどうすればよいですか?

以下にFlask-SQLAlchemyテーブルのモデル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

ここに add_userはカスタムメソッドです。だから私がadd_userメソッドは、名前をUserテーブルに追加する必要があります。

同様に、そのモデル自体でCRUD操作のカスタムメソッドを作成するにはどうすればよいですか?

9
Kumaran

これを実現するには、おそらくclassmethodを使用することをお勧めします。

_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()
_

このようにして、User.create(name="kumaran")を使用して、データベースにコミットされる新しいユーザーを作成できます。

さらに良いことに、このメソッドや他のメソッドのミックスインを作成して、機能を他のモデルで簡単に再利用できるようにすることをお勧めします。

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

次に、次のように多重継承を使用して、モデルでこの機能を再利用できます。

_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
_
14
Patrick Allen

これがFlask-SQLAlchemyに関連するかどうかはわかりませんが、基本的なSQLAlchemyには、Mixinクラスの作成やBaseクラスの拡張の例があります。

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

例えば.

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))
0
barakbd