在上一章中,我们已经创建好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方法。
本文对应的源码下载 (为了方便大家理解,源码包只放了这两章所用到的一些代码)
原文出处:https://www.cnblogs.com/EmptyFS/p/9410998.html
共同学习,写下你的评论
评论加载中...
作者其他优质文章