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_music、t_vedio表结构如下图所示
在BaseColumn中还定义了两个共有方法,分别是save、delete,在对数据进行增删改查的时候,就可以直接通过模型类实例来调用这两个方法,实现数据的存储以及删除了,实例代码片段如下
# 插入数据
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
grain 用户 2023-08-26T00:41:04
我好像摸索出来了,哈哈哈o(* ̄︶ ̄*)o,大佬博客做的真不错