展开

文章目录

修改历史

Flask-SQLAlchemy一些高级用法记录(2)

2023-07-09 12:47:19 Python 259

简介

在上一节中介绍了如何使用Mixin去定义公共字段,最近在实际工作中遇到了一些问题,同时也学到了一些新的高级用法,在本文中记录一下。

1. 使用Mixin来定义普通公共方法

上一节中介绍了使用Mixin来定义公共字段,在最近的工作中,除了可以定义普通的公共字段之外还可以通过继承的方式定义普通的功能方法,如下面的代码示例

from sqlalchemy.ext.declarative import declared_attr

class BaseColumn:
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    def save(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

定义上述类之后,之后在定义新的类模型时,就可以通过继承的方式去继承公共属性以及公共方法,如下示例

class Music(BaseColumn, db.Model):
    __tablename__ = 't_music'

    name = db.Column(db.String(512), default='', comment='歌曲名称')
    author = db.Column(db.String(512), default='', comment='歌手名')


class Video(BaseColumn, db.Model):
    __tablename__ = 't_video'

    name = db.Column(db.String(512), default='', comment='电影名称')
    director = db.Column(db.String(512), default='', comment='电影导演')

通过类对象的方式继承,在子类中字段都会被自动放到最前面,如果想放到子类字段的后面,参考上一节的内容!

t_musict_vedio表结构如下图所示

BaseColumn中还定义了两个共有方法,分别是savedelete,在对数据进行增删改查的时候,就可以直接通过模型类实例来调用这两个方法,实现数据的存储以及删除了,实例代码片段如下

# 插入数据
video = Video(name='让子弹飞',director='姜文')
video.save()

# 删除数据
v = Video.query.get(id)
v.delete()

2. 定义类方法

除了上述的实例方法之外,还可以定义类方法。在使用flask-sqlalchemy的进行查询的时候一般都是ModelName.query的方式去进行查询的,下面示例代码片段演示了如何定义一个update_or_insert的类方法

class BaseColumn:
    @classmethod
    def update_or_insert(cls, condition: tuple, **kwargs):
        """
        更新已有数据或者插入新的数据

        :param condition: 查询条件
        :param kwargs: 需要更新或者插入的字段
        :return: 类实例对象
        """
        existed = cls.query.filter(*condition)
        if existed.first():
            existed.update(kwargs)
            existed = existed.first()
        else:
            existed = cls(**kwargs)
            db.session.add(existed)
        db.session.commit()
        return existed

通过@classmethod装饰器将update_or_insert变成类方法,在子类查询的时候就可以通过下面的示例代码片段进行使用了

video = Video.update_or_insert(Video.name == name, name=name, director=director)
video.save()

完整的示例代码可以查询github仓库,仓库地址:https://github.com/weijiang1994/blog-demo/tree/main/orm_feature

5条评论


grain 用户

我好像摸索出来了,哈哈哈o(* ̄︶ ̄*)o,大佬博客做的真不错

Macv 博主 回复:grain

哈哈哈 厉害了呀~


grain 用户

请问大佬,我最近在github上下载了你的博客网站源码,请问如何进入后台管理界面呢?


grain 用户

666

Macv 博主 回复:grain

777


Macv 博主

666