Flaskz介绍2--数据模型扩展类

Flaskz提供了BaseModelMixin和ModelMixin两个数据库模型扩展类,封装了常用的增删改查等方法,并添加了数据校验,批量操作等功能。

将分散在函数中的业务逻辑和数据处理抽象到模型类层级集中处理,提高系统的整体性和模块化, 也将开发人员从琐碎的数据库操作中解放出来,从而可以更加专注于业务功能的实现。

本文不涉及数据库表的迁移操作,感兴趣的可以参考Alembic

BaseModelMixin

BaseModelMixin类主要是封装了数据库的增删改查基本操作。

增加数据

  • add_db(data)
    • 功能:将dict对象(json数据)插入到模型对应的数据库表中

      添加过程中会对数据进行处理,对不需要录入的字段(数据库自动生成)进行过滤

      同时也会对包含在data中的关系数据进行级联插入

                                      
                                          class User(ModelMixin):
                                              id = Column(Integer, primary_key=True, autoincrement=True)  # 自增主键
                                              name = Column(String(32), unique=True, nullable=False) # name不能重复
                                              age = Column(Integer)
                                              addresses = relationship(Address, cascade='all,delete,delete-orphan', lazy='joined') # Address关系映射
                                              #...
                                              updated_at = Column(DateTime(), default=datetime.now, onupdate=datetime.now) # 数据更新时间,系统自动维护
                                              # auto_columns列表中的属性,即使在传递过来的数据中存在,也会在添加/编辑时被过滤掉,列元素可以是列名字也可以是列对象。
                                              like_columns = ['name', description] # 可以进行模糊查询的属性列表,参考query_pss
                                              auto_columns = ['id', updated_at] # 系统自动生成&维护,增加/编辑时不会受传递的参数影响
                                      
                                  
    • 参数:
      • {dict}data --要添加的dict对象
    • 返回:添加成功的模型类instance对象
    • 示例:
                                      
                                          User.add_db({
                                              "name":"taozh",
                                              "age":18,
                                              "id":"10", # id属性会被过滤掉,数据库自动生成
                                              "updated_at":"Tue, 10 Sep 2021 12:01:27 GMT" # updated_at属性会被过滤掉,系统自动生成
                                          })
                                      
                                  
  • check_add_data(data)
    • 功能:对于要添加的数据进行校验,默认对数据的唯一性进行了校验,可以重载以增加自定义校验,例如)数据完整性/数据格式等。
    • 参数:
      • {dict}data --要添加的dict数据
    • 返回:True或者校验失败原因,如果不是True则表示校验失败,并直接返回,如果数据唯一性校验发现数据已存在,则返回res_status_codes.db_data_already_exist
    • 示例:
                                      
                                          user1 = {"name":"taozh","age":18}
                                          User.check_add_data(user1) # True
                                          User.add_db(user1)
                                          User.check_add_data(user1) # res_status_codes.db_data_already_exist
                                      
                                  
  • bulk_add(items, with_relationship=False)
    • 功能:一次性添加多条记录
    • 参数:
      • {list}items --要添加的多条数据列表
      • {boolean}with_relationship --是否需要添加关联关系,默认为False

        -如果为True,则会添加关联关系,比如user的addresses

        -如果为False,则会忽略关联关系,此种方式效率更高,但是没有类似add_db的属性过滤功能

    • 示例:
                                      
                                          User.bulk_add([
                                              {"name":"user1","age":11},
                                              {"name":"user2","age":12},
                                              {"name":"user3","age":13}])
                                      
                                  

删除数据

  • delete_db(pk_value)
    • 功能:根据主键删除对应的数据
    • 参数:
      • pk_value --要删除数据的主键值,比如id,name等
    • 返回:删除的模型类instance对象
    • 示例:
                                      
                                          ins = User.delete_db(10) # 将id为10的User记录删除
                                      
                                  
  • delete_by(by_dict)
    • 功能:删除符合指定条件的数据
    • 参数:
      • {dict}by_dict --指定的属性集合,符合条件的数据会被删除
    • 返回:删除数据的数量
    • 示例:
                                      
                                          delete_count = SysActionLog.delete_by({'type': 'login'}) # 删除所有type为login的操作日志
                                      
                                  
  • delete_by_query(query_options, no_criterion_allowed=False)
    • 功能:删除符合指定查询条件的数据
    • 参数:
      • {dict}query_options --指定的查询条件,符合条件的数据会被删除
      • {boolean}no_criterion_allowed --如果没有指定query_options查询条件,
        • 如果no_criterion_allowed=True,删除全部数据
        • 如果no_criterion_allowed=False,不做删除,返回0
    • 返回:删除数据的数量
    • 示例:
                                      
                                          # 删除2023-01-01之前type为login的操作日志
                                          delete_count = SysActionLog.delete_by_query({
                                                              'type':'login',
                                                              'created_at': {
                                                                  '<': '2023-01-01 00:00:00'
                                                              }})
                                      
                                  
  • check_delete_data(pk_value)
    • 功能:对于要删除的主键值进行校验,默认检查主键值对应的记录是否存在
    • 参数:
      • pk_value --要删除数据的主键值,比如id,name等
    • 返回:True或者校验失败原因,如果不是True则表示校验失败,并直接返回,如果主键值对应的记录在数据库表中不存在,则返回res_status_codes.db_data_not_found
    • 示例:
                                      
                                          user = User.add_db({"name":"taozh","age":18}) # user.id=123
                                          User.check_delete_data(123) # True
                                          User.check_delete_data(-123) # res_status_codes.db_data_not_found
                                      
                                  
  • bulk_delete(items)
    • 功能:一次性删除多条记录,会对items列表进行遍历查询,然后逐个删除
    • 参数:
      • {list}items -- 要删除的记录属性集/主键值列表
    • 示例:
                                      
                                          User.bulk_delete([
                                              10,20,  # 通过主键值进行删除
                                              {"name":"user2"}, # 通过属性集进行删除
                                              {"name":"user3"}])
                                      
                                  
  • clear_db()
    • 功能:清空模型的所有数据
    • 返回:
      • {int}count --清空的数据总数
    • 示例:
                                      
                                          User.clear_db()
                                      
                                  

修改数据

  • update_db(data)
    • 功能:根据dict对象(json数据)中的主键从数据库查找对应的记录,并进行更新,同时也会对data中包含的关系属性进行更新或替换

      请注意这里采用的是局部更新而非替换,只有data中包含的属性才会进行更新,如果不包含则保留原值

      更新过程中会对数据进行处理,对不需要录入的字段(数据库自动生成/auto_columns)进行过滤

    • 参数:
      • {dict}data --要修改的数据,必须带有主键值
    • 返回:更新成功的模型类instance对象,如果没有找到记录,则返回None
    • 示例:
                                      
                                          User.update_db({
                                              "id":"10", # 根据id查找到对应的user记录
                                              "age":19, # 只更新了age属性,name属性保持不变
                                              "updated_at":"Tue, 10 Sep 2021 12:01:27 GMT" # updated_at属性会被过滤掉,系统自动生成
                                          })
                                      
                                  
  • check_update_data(data)
    • 功能:对于要修改的数据进行校验,默认会对数据是否存在以及属性的唯一性进行校验,可以重载以增加自定义校验,例如)数据完整性/数据格式等。
    • 参数:
      • {dict}data --要修改的数据
    • 返回:True或者校验失败原因,如果不是True则表示校验失败,并直接返回

      如果要修改的数据不存在,则返回res_status_codes.db_data_not_found

      如果数据唯一性校验发现除当前数据以外的数据已存在,则返回res_status_codes.db_data_already_exist

    • 示例:
                                      
                                          user1 = User.add_db({"name":"user1","age":18}) # user1.id = 10
                                          user2 = User.add_db({"name":"user2","age":18}) # user2.id = 11
                                          User.check_update_data({"id":10,"age":19}) # True
                                          User.check_update_data({"id":10,"name":"user1","age":19}) # True,虽然id为10的记录name为user1,但是因为修改的是当前数据,所以唯一性校验成功
                                          User.check_update_data({"id":10,"name":"user2","age":19}) # res_status_codes.db_data_already_exist,name为user2的记录已经存在且不是当前数据,唯一性校验失败
                                          User.check_update_data({"id":100,"age":19}) # res_status_codes.db_data_not_found,数据不存在
                                      
                                  
  • bulk_update(items, with_relationship=False)
    • 功能:一次性更新多条记录
    • 参数:
      • {list}items --要更新的多条数据列表
      • {boolean}with_relationship --是否需要更新关联关系数据,默认为False

        -如果为True,则会更新关联关系数据,比如替换user的addresses

        -如果为False,则会忽略关联关系,此种方式效率更高,但是没有类似update_db的属性过滤功能

    • 示例:
                                      
                                          User.bulk_update([
                                              {"id":11,"age":12},
                                              {"id":12,"age":13},
                                              {"id":13,"age":14}])
                                      
                                  

to_dict(option=None) 查询数据

  • query_all()
    • 功能:查询当前模型类的所有记录对象,并以列表的形式返回
    • 返回:包含所有记录对象的列表
    • 示例:
                                      
                                          User.query_all()
                                      
                                  
  • query_by(by_dict, return_first=False)
    • 功能:根据属性条件查询符合条件的记录对象,根据return_first参数不同,返回的值可能不同(对象/列表)
    • 参数:
      • {dict}by_dict --查询条件的属性集合
      • {boolean}return_first -- 是否返回符合条件的第一个对象,默认是False,即返回列表

        -如果为True,返回符合条件的第一个对象

        -如果为False,返回符合条件的数据列表

    • 返回:符合条件的对象列表或第一个对象
    • 示例:
                                      
                                          User.query_by({"age":18}) # 查询所有age=18的user记录
                                          User.query_by({"name":"user1"},True) # 查询name=user1的第一条记录
                                      
                                  
  • query_by_pk(pk_value)
    • 功能:根据主键值查询符合条件的记录对象
    • 参数:
      • pk_value --要查询记录的主键值
    • 返回:主键值对应的记录对象
    • 示例:
                                      
                                          User.query_by_pk(10) # 查询主键id=10的user记录
                                      
                                  
  • query_pss(pss_option)
    • 功能:pss=page+search+sort,根据分页/排序/搜索/等条件查询符合条件的记录列表,这是功能最强大的一个查询函数,可以实现各种查询功能
    • 参数:
      • {dict}pss_option --分页排序搜索等查询条件, 建议先通过 parse_pss 方法将查询参数转换再调用query_pss方法,有如下可选项
        • order --查询结果集的排序方式,支持多列排序,如果不指定,默认使用get_query_default_order的order(默认是主键对应的列)
        • limit --查询结果集的限制条数,即每次返回的最多记录数,只有>0才会起作用
        • offset --查询结果集的偏移起始值,即跳过多少条记录,只有>0才会起作用
        • filter_likes -- 通过OR/AND连接的多个查询条件集合,用于模糊查询(包含&不包含),只有查询payload或模型类中指定的like_columns中的列/属性才会进行模糊查询
        • filter_ands -- 通过AND进行连接的多个查询条件集合
        • filter_ors -- 通过OR进行连接的多个查询条件集合
        • group -- 查询分组
        • relationships -- relationship相关的查询条件集合
    • 返回:符合条件的对象列表
    • 示例:
                                      
                                          result, result = TemplateModel.query_pss(parse_pss(
                                              TemplateModel, {   # FROM templates
                                                  "search": {                     # 条件查询
                                                      "like": "t",                    # -模糊查询: name like '%t%' OR description like '%t%' (TemplateModel.like_columns = ['name', description])
                                                      "age": {                        # -范围查询: AND (age>1 AND age<20)
                                                          ">": 1,                     # operator:value, operators)'='/'>'/'<'/'>='/'<='/'BETWEEN'/'LIKE'/'IN'
                                                          "<": 20
                                                      },
                                                      "email": "taozh@focus-ui.com",  # -精确查询: AND (email='taozh@focus-ui.com')
                                                      # "address.city": "New York",     # -relation字段精确查询
                                                      "_ors": {                       # -通过OR进行连接的多个查询条件集合: AND (country='America' OR country='Canada')
                                                          "country": "America||Canada"
                                                      },
                                                      "_ands": {                      # -通过AND进行连接的多个查询条件集合: AND (grade>1 AND grade<5)
                                                          "grade": {
                                                              ">": 1,
                                                              "<": 5
                                                          }
                                                      }
                                                  },
                                                  "sort": {                       # 查询结果集的排序方式: ORDER BY templates.name ASC
                                                      "field": "name",                # -排序属性
                                                      "order": "asc"                  # -排序方式: asc/desc
                                                  },
                                                  # "sort":[                      # 多列排序: ORDER BY templates.name ASC, templates.age DESC
                                                  #     {"field": "name", "order": "asc"},
                                                  #     {field": "address.city", "order": "desc"} # -relation字段排序
                                                  # ],
                                                  "page": {                       # 分页: LIMIT ? OFFSET ? (20, 0)
                                                      "offset": 0,                    # -偏移为0
                                                      "size": 20                      # -每页20条记录
                                                  },
                                                  "group": "email"                # 分组: GROUP BY templates.email
                                              }))
                                          #以上查询条件通过parse_pss方法转换以后,等价下列查询条件
                                          TemplateModel.query_pss({
                                              "filter_likes": ["name like '%t%'", "description like '%t%'"],
                                              "filter_ands": ["email='taozh@focus-ui.com'", "age>1", "age<20", "grade>1", "grade<5"],
                                              "filter_ors": ["country='America'", "country='Canada'"],
                                              "offset": 0,
                                              "limit": 20,
                                              "order": [asc(TemplateModel.name)]  # [asc(TemplateModel.name), desc(TemplateModel.age)],
                                              "group": [TemplateModel.email]
                                          })
                                      
                                  
  • get_query_default_order()
    • 功能:返回查询时默认使用的排序方式,默认使用系统的主键进行排序,可重写以自定义默认排序
    • 返回:默认的排序方式
    • 示例:
                                      
                                          class Log:
                                              #...
                                              updated_at = Column(DateTime(), default=datetime.now, onupdate=datetime.now)
                                              def get_query_default_order(cls):
                                                  return desc(cls.updated_at) # 使用更新时间的倒序作为查询时默认的排序方式
                                      
                                  
  • count(search=None)
    • 功能:查询当前模型类的记录数,如果指定了search则返回符合条件的记录数,如果search为None则返回记录总数
    • 返回:
      • {int}count --记录数(全量/条件)
    • 版本:>= v1.6
    • 示例:
                                      
                                          SysActionLog.count() # 总数
      
                                          SysActionLog.count(parse_pss( # 符合条件的记录数
                                              TemplateModel, {   # FROM templates
                                                  "search": {                         # WHERE
                                                      "like": "t",                    # name like '%t%' OR description like '%t%' (TemplateModel.like_columns = ['name', description])
                                                      "age": {                        # AND (age>1 AND age<20)
                                                          ">": 1,                     # operator:value, operators)'='/'>'/'<'/'>='/'<='/'BETWEEN'/'LIKE'/'IN'
                                                          "<": 20
                                                      },
                                                      "email": "taozh@focus-ui.com",  # AND (email='taozh@focus-ui.com')
                                                      "_ors": {                       # AND (country='America' OR country='Canada')
                                                          "country": "America||Canada"
                                                      },
                                                      "_ands": {                      # AND (grade>1 AND grade<5)
                                                          "grade": {
                                                              ">": 1,
                                                              "<": 5
                                                          }
                                                      }
                                                  }
                                              }))
                                      
                                  

数据序列化

  • to_dict(option=None)
    • 功能:将模型对象转换为包含属性的字典,除了对象的自身属性,也可以通过选项控制级联对象的输出
    • 参数:
      • {dict|None}option --转换选项,可以设置cascade/include/exclude等选项,请参考ins_to_dict方法

        默认通过to_dict_field_filter回调函数对属性进行控制,如果设置了include/exclude,to_dict_field_filter将不起作用

    • 返回:包含对象属性的字典
    • 示例:
                                      
                                          User.to_dict({
                                              "cascade":1     # 会将第一级关系对象输出为字典的属性,比如addresses关系列表,就会以addresses:[{...},{...}]的格式输出到字典中
                                              "exclude": ["password", "last_login_at"],   # exclude中的字段不会返回,一般不直接设置,而是通过重写to_dict_field_filter方法进行属性过滤
                                              "addresses":{ # 也可以对于级联对象的输出进行设置
                                                  "include": ["id","city"],   # 只有include中的字段才会返回,include的优先级>exclude,,一般不直接设置,而是通过重写to_dict_field_filter方法进行属性过滤
                                              }
                                          })
                                      
                                  
  • to_dict_field_filter(field)
    • 功能:用于模型对象转换为字典对象时,对属性是否转换进行控制,一般用于重写定制化,见示例代码
    • 参数:
      • {string}filed --待检测的field属性,比如id/name/age等
    • 返回:
      • -True,则field会被输出到字典中
      • -False,则field不会输出到字典中
    • 示例:
                                      
                                          class User(ModelBase, ModelMixin):
                                              #...
                                              @classmethod
                                              def to_dict_field_filter(cls, field):
                                                  return field not in ['password', 'last_login_at'] and super().to_dict_field_filter(field) # password/last_login_at属性不会输出到字典中
                                      
                                  

其它

  • get_columns()
    • 功能:返回模型类所有列的列表
    • 返回:所有列组成的列表
    • 示例:
                                      
                                          for col in cls.get_columns():
                                              field = cls.get_column_field(col)  # col.key
                                      
                                  
  • get_column_field(col)
    • 功能:返回指定列的key属性(对应数据库中表的列名),如果通过info进行了设置,则返回info中的field属性
    • 参数:
      • {Column}col --指定的列对象
    • 返回:列的key/field--数据库表的列名
    • 示例:
                                      
                                          name = Column(String(32), unique=True, nullable=False) # 返回"name"
                                          system_default = Column('default', Boolean, default=False, info={'field': 'system_default'}) # 返回"system_default",当列名和表名不一致时使用
                                      
                                  
  • get_primary_column()
    • 功能:获取模型类的主键列
    • 返回:模型类的主键列
    • 示例:
                                      
                                          User.get_primary_column() # id列对象
                                      
                                  
  • like_columns
    • 功能:定义可以进行全局模糊查询的列,在BaseModelMixin.query_pss方法中使用
    • 示例:
                                      
                                          class User:
                                              id = Column(Integer, primary_key=True, autoincrement=True)
                                              name = Column(String(32), unique=True, nullable=False)
                                              description = Column(String(255))
                                              #...
                                              like_columns = ['name', description] # 可以进行模糊查询的属性列表,可以是字符串也可以是列对象
                                      
                                  
  • auto_columns
    • 功能:定义系统自动生成的属性列表,在添加/修改数据时使用,在auto_columns定义的属性会忽略data中的属性,而是系统自动生成

      也可以通过列的info属性进行等价设置,见示例created_at列,不过还是建议通过auto_columns进行统一设置

    • 示例:
                                      
                                          class User:
                                              id = Column(Integer, primary_key=True, autoincrement=True)
                                              name = Column(String(32), unique=True, nullable=False)
                                              created_at = Column(DateTime(), default=datetime.now, info={'auto': True}) # created_at列的值,也会忽略data中的属性,系统自动生成
                                              updated_at = Column(DateTime(), default=datetime.now, onupdate=datetime.now)
                                              #...
                                              auto_columns = ['id', updated_at] # 自动生成的列,增加/编辑时会忽略data中的属性
                                      
                                  

ModelMixin

ModelMixin继承自BaseModelMixin,在其基础上增加了流程控制和逻辑校验,主要用于业务流程的定制和扩展,并针对API请求等场景进行了相关的封装,以便于模型数据和路由处理函数的对接。

大多数业务模型类都建议继承ModelMixin,尤其是要跟路由处理函数进行交互的模型类。

增加数据

  • add(data)
    • 功能:将dict数据插入到模型对应的数据库表中, 在BaseModelMixin的add_db方法基础上添加了get_add_data/check_add_data/before_add/after_add等函数回调,并对异常进行了try/catch处理

      各个函数的调用过程如下:

      1. get_add_data:调用get_add_data函数返回要添加的data,可以重载用于添加/移除属性,默认不做处理直接返回传入的data
      2. check_add_data:调用check_add_data函数进行数据校验,如果结果!=True,则表示校验失败,会直接返回,默认会对数据唯一性约束进行检查,参考BaseModelMixin.check_add_data方法
      3. before_add:调用before_add函数进行数据逻辑处理,一般用于在入库之前和其他系统进行对接和业务逻辑处理,如果返回结果!=True,则表示添加失败,会直接返回,默认返回True
      4. add_db:调用add_db函数,将数据插入到数据库表中,参考BaseModelMixin.add_db方法
      5. after_add:调用after_add函数进行数据的逻辑处理,一般用于清理数据。例如,用于角色管理中确保只有一个是默认值
    • 参数:
      • {dict}data --要添加的dict数据
    • 返回:一个带有成功失败标志和结果的元组,可以通过标志进行逻辑判断
      • -(True,instance),添加成功,返回True和添加成功的instance对象组成的元组
      • -(False,fail_reason),添加失败,返回False和失败原因组成的元组,失败原因参考调用过程
    • 示例:
                                      
                                          User.add({
                                              "name":"taozh",
                                              "age":18
                                          })
                                      
                                  
  • get_add_data(data)
    • 功能:对于要添加的数据进行处理,一般用于重载以附加属性/移除属性,请参考ModelMixin.add方法
    • 参数:
      • {dict}data --要添加的dict数据
    • 返回:处理以后的dict数据,默认不做处理直接返回
  • before_add(data)
    • 功能:在将数据添加到数据库之前进行逻辑处理,比如和其他系统进行对接,一般用于重载以添加业务逻辑,请参考ModelMixin.add方法
    • 参数:
      • {dict}data --要添加的dict数据
    • 返回:
      • -True,表示处理成功或者不需要处理
      • -False,表示处理失败
    • 示例:
                                      
                                          class NSOModelMixin:
                                              #...
                                              """
                                              操作DB之前,先调用NSO
                                              -NSO操作成功,操作数据库
                                              -NSO操作失败,直接返回到客户端
                                              """
                                              @classmethod
                                              def before_add(cls, data):
                                                  return cls.nso_add(data) # 调用NSO进行配置下发
      
                                              @classmethod
                                              def nso_add(cls, data):
                                                  nm = cls.get_nso_model()
                                                  if nm:
                                                      nso_data = cls.get_nso_data(data, 'add')
                                                      if nso_data is None:
                                                          return status_codes.nso_request_params_err
      
                                                      result = nm.add(nso_data)
                                                      if result[0] is False: # 添加失败
                                                          return result[1]   # 返回失败原因
                                                  return True                # 添加成功,返回True
                                      
                                  
  • after_add(data, instance, before_result)
    • 功能:无论添加成功还是失败都会调用,可以重载after_add,进行一些清理工作
    • 参数:
      • {dict}data:要添加的dict数据
      • {BaseModelMixin}instance:添加成功的instance对象,如果失败可能是空
      • {*}before_result:调用before_add的结果,一般用于处理调用before_add成功,但是插入数据库失败的场景

删除数据

  • delete(pk_value)
    • 功能:根据主键删除对应的数据, 在BaseModelMixin的delete_db方法基础上添加了get_delete_data/check_delete_data/before_delete/after_delete等函数回调,并对异常进行了try/catch处理

      各个函数的调用过程如下:

      1. get_delete_data:调用get_delete_data函数返回要删除的主键值,默认不做处理直接返回传入的pk_value
      2. check_delete_data:调用check_delete_data函数进行数据校验,如果结果!=True,则表示校验失败,会直接返回,默认会对数据的存在性进行检查,参考BaseModelMixin.check_delete_data方法
      3. before_delete:调用before_delete函数进行数据逻辑处理,一般用于在删除之前和其他系统进行对接和业务逻辑处理,如果返回结果!=True,则表示添加失败,会直接返回,默认返回True
      4. delete_db:调用delete_db函数,将数据从数据库中删除,参考BaseModelMixin.delete_db方法
      5. after_delete:调用after_delete函数进行数据的逻辑处理,一般用于清理数据。
    • 参数:
      • pk_value --要删除的主键值
    • 返回:一个带有成功失败标志和结果的元组,可以通过标志进行逻辑判断
      • -(True,instance),删除成功,返回True和删除成功的instance对象组成的元组
      • -(False,fail_reason),删除失败,返回False和失败原因组成的元组,失败原因参考调用过程
    • 示例:
                                      
                                          User.delete(10)
                                      
                                  
  • get_delete_data(pk_value)
    • 功能:返回待删除的主键值
    • 参数:
      • pk_value --要删除的主键值
    • 返回:待删除的主键值,默认不做处理直接返回
  • before_delete(pk_value)
    • 功能:在将数据从数据库删除之前进行逻辑处理,比如和其他系统进行对接,一般用于重载以删除对应的业务逻辑,请参考ModelMixin.delete方法
    • 参数:
      • pk_value --要删除的主键值
    • 返回:
      • -True,表示处理成功或者不需要处理
      • -False,表示处理失败
    • 示例:
                                      
                                          class NSOModelMixin:
                                              """
                                              操作DB之前,先调用NSO
                                              -NSO操作成功,操作数据库
                                              -NSO操作失败,直接返回到客户端
                                              """
      
                                              #...
                                              @classmethod
                                              def before_delete(cls, pk_value):
                                                  return cls.nso_delete(pk_value) # 调用NSO删除对应的配置
      
                                              @classmethod
                                              def nso_delete(cls, pk_value):
                                                  """
                                                  一般NSO删除都是通过name进行操作
                                                  :param pk_value:
                                                  :return:
                                                  """
                                                  nm = cls.get_nso_model()
                                                  if nm:
                                                      delete_data = cls.get_nso_delete_data(pk_value)
                                                      if delete_data is None:
                                                          return res_status_codes.db_data_not_found
      
                                                      result = nm.delete(delete_data)
                                                      if result[0] is False:          # 删除失败
                                                          return result[1]            # 返回失败原因
                                                  return True                         # 删除成功,返回True
                                      
                                  
  • after_delete(pk_value, instance, before_result)
    • 功能:无论删除成功还是失败都会调用,可以重载after_after_delete,进行一些清理工作
    • 参数:
      • pk_value:要删除对象的主键值
      • instance:删除成功的instance对象,如果失败可能是空
      • before_result:调用before_delete的结果,一般用于处理调用before_delete成功,但是删除数据库失败的场景

修改数据

  • update(data)
    • 功能:根据dict对象(json数据)中的主键从数据库查找对应的记录,并进行更新, 在BaseModelMixin的update_db方法基础上添加了get_update_data/check_update_data/before_update/after_update等函数回调,并对异常进行了try/catch处理

      各个函数的调用过程如下:

      1. get_update_data:调用get_update_data函数返回要修改的data,可以重载用于添加/移除属性,默认不做处理直接返回传入的data
      2. check_update_data:调用check_update_data函数进行数据校验,如果结果!=True,则表示校验失败,会直接返回,默认会对数据是否存在以及属性的唯一性进行校验,参考BaseModelMixin.check_update_data方法
      3. before_update:调用before_update函数进行数据逻辑处理,一般用于在修改之前和其他系统进行对接和业务逻辑处理,如果返回结果!=True,则表示添加失败,会直接返回,默认返回True
      4. update_db:调用add_db函数,更新数据库中的记录,参考BaseModelMixin.update_db方法
      5. after_update:调用after_update函数进行数据的逻辑处理,一般用于清理数据。
    • 参数:
      • {data}data --要修改的dict数据,必须带有主键值
    • 返回:一个带有成功失败标志和结果的元组,可以通过标志进行逻辑判断
      • -(True,instance),修改成功,返回True和修改成功的instance对象组成的元组
      • -(False,fail_reason),修改失败,返回False和失败原因组成的元组,失败原因参考调用过程
    • 示例:
                                      
                                          User.update({
                                              "id":10
                                              "name":"taozh",
                                              "age":19
                                          })
                                      
                                  
  • get_update_data(data)
    • 功能:对于要修改的数据进行逻辑处理,一般用于重载以附加属性/移除属性,请参考ModelMixin.update方法
    • 参数:
      • {data}data --要修改的dict数据
    • 返回:处理以后的dict数据,默认不做处理直接返回
  • before_update(data)
    • 功能:更新数据库之前进行逻辑处理,比如和其他系统进行对接,一般用于重载以添加业务逻辑,请参考ModelMixin.update方法
    • 参数:
      • {data}data --要修改的dict数据
    • 返回:
      • -True,表示处理成功或者不需要处理
      • -False,表示处理失败
    • 示例:
                                      
                                          class NSOModelMixin:
                                              """
                                              操作DB之前,先调用NSO
                                              -NSO操作成功,操作数据库
                                              -NSO操作失败,直接返回到客户端
                                              """
                                              @classmethod
                                              def before_update(cls, data):
                                                  return cls.nso_update(data)    # 调用NSO更新设备上的配置
      
                                              @classmethod
                                              def nso_update(cls, data):
                                                  nm = cls.get_nso_model()
                                                  if nm:
                                                      nso_data = cls.get_nso_data(data, 'update')
                                                      if nso_data is None:
                                                          return status_codes.nso_request_params_err
                                                      result = nm.update(nso_data)
                                                      if result[0] is False:          # 更新失败
                                                          return result[1]            # 返回失败原因
                                                  return True                         # 更新成功,返回True
                                      
                                  
  • after_update(data, instance, before_result)
    • 功能:无论修改成功还是失败都会调用,可以重载after_update,进行一些清理工作
    • 参数:
      • data:要修改的数据
      • instance:修改成功的instance对象,如果失败可能是空
      • before_result:调用before_update的结果,一般用于处理调用before_update成功,但是修改数据库失败的场景

查询数据

  • query_all()
    • 功能:在BaseModelMixin的query_all基础上,添加了try/catch异常处理
    • 返回:一个带有成功失败标志和结果的元组,这也是和BaseModelMixin.query_all函数的主要区别,BaseModelMixin.query_all返回的是结果列表
      • -(True,instance_list),查询成功,返回True和包含所有记录对象的列表组成的元组
      • -(False,fail_reason),查询失败,返回False和失败原因组成的元组
    • 示例:
                                      
                                          class User(ModelBase, ModelMixin) # 继承自ModelMixin
                                              pass
                                          User.query_all() #返回的是元组
      
                                          class Address(ModelBase, BaseModelMixin) # 继承自BaseModelMixin
                                              pass
                                          Address.query_all() #返回的是结果列表
                                      
                                  
  • query_pss(pss_option)
    • 功能:在BaseModelMixin的query_pss基础上,添加了try/catch异常处理,请参考BaseModelMixin.query_pss方法
    • 返回:一个带有成功失败标志和结果的元组,这也是和BaseModelMixin.query_pss函数的主要区别,BaseModelMixin.query_pss返回的是结果列表
      • -(True,instance_list),查询成功,返回True和包含所有记录对象的列表组成的元组
      • -(False,fail_reason),查询失败,返回False和失败原因组成的元组
    • 示例:
                                      
                                          class User(ModelBase, ModelMixin) # 继承自ModelMixin
                                              pass
                                          User.query_pss({...}) #返回的是元组
      
                                          class Address(ModelBase, BaseModelMixin) # 继承自BaseModelMixin
                                              pass
                                          Address.query_pss({...}) #返回的是结果列表