继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

我的第一个python web开发框架(27)——定制ORM(三)

精慕HU
关注TA
已关注
手记 235
粉丝 24
获赞 115

在上一章中,我们已经创建好ORM的基类了,接下来要做的就是将基类的常用方法一一实现。

  首先我们来看看之前项目中,最常见的获取指定主键的记录实体

复制代码

@get('/api/product/<id:int>/')def callback(id):    """
    获取指定id的产品记录实体    """
    sql = """select * from product where id = %s""" % (id,)    # 读取记录
    result = db_helper.read(sql)    if result:        return web_helper.return_msg(0, '成功', result[0])    else:        return web_helper.return_msg(-1, "查询失败")

复制代码

  从代码中可以看到,我们需要执行select * from product where id = xx从数据表中查询到我们想要的数据。

  要封装成ORM的方法,我需要需要注意下面几项事情:

  1.方法名必须是简单易懂的

  2.方法需要接收指定的主键值

  3.sql需要在方法中进行组装

  根据这些要求,我们可以很容易写出这个方法

复制代码

    def get_model_for_pk(self, pk):        """通过主键值获取数据库记录实体"""
        if not pk:            return {}        # 组装查询条件
        wheres = '%s = %s' % (self.__pk_name, str(pk))        # 合成sql语句
        sql = "select %(column_name_list)s from %(table_name)s where %(wheres)s" % \
              {'column_name_list': self.__column_name_list, 'table_name': self.__table_name, 'wheres': wheres}        # 初化化数据库链接
        with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:            # 执行sql语句
            _result = db.execute(sql)            # 对返回的内容进行处理
            if _result:
                result = _result[0]            else:
                result = {}        return result

复制代码

  我们通过方法名(get_model_for_pk)应当可以知道,我们是通过主键来获取指定的记录实体内容。

  该方法需要传入的参数值是主键值pk

  在接收到主健值以后,我们需要对它进行简单的判断处理,如果它为空则直接返回空字典。

  在组合sql前,我们需要选对查询条件进行组装,这里我们直接使用self.__pk_name,在上一章初始化时定义好的默认项,在这里不直接使用id做为条件字段,是为了当出现主键名称为其他字符时,可以灵活处理。比如订单表使用code为主键时,就可以直接绑定code而不是自增id了。比如self.__pk_name初始值是id,主键pk值是1,那么组装后的查询条件为 id=1

  然后直接调用默认项查询字段名称self.__column_name_list和表名称self.__table_name来合成sql语句。例如self.__column_name_list初始值为*,self.__table_name初始值为product,那么合成的sql语句为:select * from product where id=1

  最后调用数据库操作类db_helper来执行sql语句(这里使用widh方法来初始化数据库操作类),将执行后的结果返回主程序

 

  针对上面这个读取产品记录实体的功能,我们像上一章一样,先创建好一个产品管理的逻辑类,继承ORM基类

复制代码

#!/usr/bin/env python# coding=utf-8from logic import _logic_basefrom config import db_configclass ProductLogic(_logic_base.LogicBase):    """产品管理表逻辑类"""

    def __init__(self):        # 表名称
        __table_name = 'product'
        # 初始化
        _logic_base.LogicBase.__init__(self, db_config.DB, db_config.IS_OUTPUT_SQL, __table_name)

复制代码

  我们就可以直接改造前面的接口调用代码了

复制代码

@get('/api/product/<id:int>/')def callback(id):    """
    获取指定记录    """
    # 实例化product表操作类ProductLogic
    _product_logic = product_logic.ProductLogic()    # 执行get_model_for_pk()方法,获取记录实体
    model = _product_logic.get_model_for_pk(id)    if model:        return web_helper.return_msg(0, '查询成功', model)    else:        return web_helper.return_msg(-1, "查询失败")

复制代码

  和前面的代码比较,代码看起来简单多了

  直接上单元测试看看执行效果

复制代码

 1 #!/usr/bin/evn python 2 # coding=utf-8 3  4 import unittest 5 from logic import product_logic 6  7 class DbHelperTest(unittest.TestCase): 8     """数据库操作包测试类""" 9 10     def setUp(self):11         """初始化测试环境"""12         print('------ini------')13 14     def tearDown(self):15         """清理测试环境"""16         print('------clear------')17 18     def test(self):19         ##############################################20         # 只需要看这里,其他代码是测试用例的模板代码 #21         ##############################################22         # 实例化product表操作类ProductLogic23         _product_logic = product_logic.ProductLogic()24         # 执行get_model_for_pk()方法,获取记录实体25         model = _product_logic.get_model_for_pk(2)26         print(model)27 28         ##############################################29 30 if __name__ == '__main__':31     unittest.main()

复制代码

  输出结果:

------ini------{'product_class_id': 1, 'place_of_origin': '广东广州', 'name': '饼干', 'id': 2, 'standard': '500g', 'is_enable': 1, 'add_time': datetime.datetime(2018, 7, 25, 23, 10, 4), 'quality_guarantee_period': '2018年12月', 'code': '20180212321211', 'content': '产品描述', 'front_cover_img': 'http://xxx.com/xxx.jpg'}------clear------

 

  做到这一步,一个简单的通过主键值读取数据表记录实体的ORM方法就完成了。

  为了让这个读取记录实体的功能能应用的更加广泛,我们还需要对它进行改造与加工。

  在开始之前,大家再继续思考一下,我们获取记录实体,通过主键查询只是众多方法中的其中一个,我们还会经常使用各种条件的组合来进行查询,读取记录实体,所以这里我们可以实现自定义条件查询的方法

复制代码

    def get_model(self, wheres):        """通过条件获取一条记录"""
        # 如果有条件,则自动添加where
        if wheres:
            wheres = ' where ' + wheres        # 合成sql语句
        sql = "select %(column_name_list)s from %(table_name)s %(wheres)s" % \
              {'column_name_list': self.__column_name_list, 'table_name': self.__table_name, 'wheres': wheres}        # 初化化数据库链接
        with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:            # 执行sql语句
            _result = db.execute(sql)            # 对返回的内容进行处理
            if _result:
                result = _result[0]            else:
                result = {}        return result

复制代码

  代码看起来与前面的get_model_for_pk()方法差不多,只不过将pk参数改为条件参数wheres,不需要再组合主键查询条件而已。由于两个函数部分代码一样,所以我们需要对get_model_for_pk()方法进行重构,直接将组装好的查询条件提交给get_model()方法来执行就可以了,将它返回的内容直接返回给主程序。

复制代码

    def get_model_for_pk(self, pk, wheres=''):        """通过主键值获取数据库记录实体"""
        if not pk:            return {}        # 组装查询条件
        wheres = '%s = %s' % (self.__pk_name, str(pk))        return self.get_model(wheres)

复制代码

  改造完成后,使用前面的单元测试跑一下,可以看到返回结果一样。增加了get_model()方法以后,我们就可以灵活的自定义任意的查询条件来读取记录了。这里要注意的是,使用get_model()方法查询时,有可能在查询时会返回多条记录,这个方法它只返回第一条记录。需要返回多条记录时,可以使用我们后续封装的其他ORM方法。

 

  

  本文对应的源码下载 (为了方便大家理解,源码包只放了这两章所用到的一些代码)

 

 原文出处:http://www.cnblogs.com/EmptyFS/p/9410998.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP