有趣的网站代码,做交友信息网站可行么,在线咨询24小时免费咨询,网站关键词优化排名软件系统几个复杂的ORM方式都已介绍完了#xff0c;剩下一些常用的删除、获取记录数量、统计合计数、获取最大值、获取最小值等方法我就不一一详细介绍了#xff0c;直接给出代码大家自行查看。1 #!/usr/bin/env python2 #codingutf-834 from common importdb_helper567 classLogicBa…几个复杂的ORM方式都已介绍完了剩下一些常用的删除、获取记录数量、统计合计数、获取最大值、获取最小值等方法我就不一一详细介绍了直接给出代码大家自行查看。1 #!/usr/bin/env python2 #codingutf-834 from common importdb_helper567 classLogicBase():8 逻辑层基础类910 def __init__(self, db, is_output_sql, table_name, column_name_list*, pk_nameid):11 类初始化12 #数据库参数13 self.__db db14 #是否输出执行的Sql语句到日志中15 self.__is_output_sql is_output_sql16 #表名称17 self.__table_name str(table_name).lower()18 #查询的列字段名称*表示查询全部字段多于1个字段时用逗号进行分隔除了字段名外也可以是表达式19 self.__column_name_list str(column_name_list).lower()20 #主健名称21 self.__pk_name str(pk_name).lower()2223 #####################################################################24 ### 执行Sql ###2526 defselect(self, sql):27 执行sql查询语句(select)28 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:29 #执行sql语句30 result db.execute(sql)31 if notresult:32 result []33 returnresult3435 defexecute(self, sql):36 执行sql语句并提交事务37 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:38 #执行sql语句39 result db.execute(sql)40 ifresult:41 db.commit()42 else:43 result []44 returnresult4546 defcopy(self, values, columns):47 批量更新数据48 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:49 #执行sql语句50 result db.copy(values, self.__table_name, columns)51 returnresult5253 defget_model(self, wheres):54 通过条件获取一条记录55 #如果有条件则自动添加where56 ifwheres:57 wheres where wheres5859 #合成sql语句60 sql select %(column_name_list)s from %(table_name)s %(wheres)s %\61 {column_name_list: self.__column_name_list, table_name: self.__table_name, wheres: wheres}62 #初化化数据库链接63 result self.select(sql)64 ifresult:65 returnresult[0]66 return{}6768 def get_model_for_pk(self, pk, wheres):69 通过主键值获取数据库记录实体70 if notpk:71 return{}72 #组装查询条件73 wheres %s %s % (self.__pk_name, str(pk))7475 returnself.get_model(wheres)7677 def get_value(self, column_name, wheres):78 79 获取指定条件的字段值————多于条记录时只取第一条记录80 :param column_name: 单个字段名如id81 :param wheres: 查询条件82 :return: 7 (指定的字段值)83 84 if notcolumn_name:85 returnNone86 elifwheres:87 wheres where wheres8889 sql select %(column_name)s from %(table_name)s %(wheres)s limit 1 %\90 {column_name: column_name, table_name: self.__table_name, wheres: wheres}91 result self.select(sql)92 #如果查询成功则直接返回记录字典93 ifresult:94 returnresult[0].get(column_name)9596 def get_value_list(self, column_name, wheres):97 98 获取指定条件记录的字段值列表99 :param column_name: 单个字段名如id100 :param wheres: 查询条件101 :return: [1,3,4,6,7]102 103 if notcolumn_name:104 column_name self.__pk_name105 elifwheres:106 wheres where wheres107108 sql select array_agg(%(column_name)s) as list from %(table_name)s %(wheres)s %\109 {column_name: column_name, table_name: self.__table_name, wheres: wheres}110 result self.select(sql)111 #如果查询失败或不存在指定条件记录则直接返回初始值112 if result andisinstance(result, list):113 return result[0].get(list)114 else:115 return[]116117 def add_model(self, fields, returning):118 新增数据库记录119 ### 拼接sql语句 ###120 #初始化变量121 key_list []122 value_list []123 #将传入的字典参数进行处理把字段名生成sql插入字段名数组和字典替换数组124 #PS:字符串使用字典替换参数时格式是%(name)s这里会生成对应的字串125 #比如126 #传入的字典为 {id: 1, name: 名称}127 #那么生成的key_list为id,name128 #而value_list为%(id)s,%(name)s129 #最终而value_list为字符串对应名称位置会被替换成相应的值130 for key infields.keys():131 key_list.append(key)132 value_list.append(%( key )s)133 #设置sql拼接字典并将数组(lit)使用join方式进行拼接生成用逗号分隔的字符串134 parameter {135 table_name: self.__table_name,136 pk_name: self.__pk_name,137 key_list: ,.join(key_list),138 value_list: ,.join(value_list)139 }140 #如果有指定返回参数则添加141 ifreturning:142 parameter[returning] , returning143 else:144 parameter[returning] 145146 #生成可以使用字典替换的字符串147 sql insert into %(table_name)s (%(key_list)s) values (%(value_list)s) returning %(pk_name)s %(returning)s %parameter148 #将生成好的字符串替字典参数值生成最终可执行的sql语句149 sql sql %fields150151 result self.execute(sql)152 ifresult:153 returnresult[0]154 return{}155156 def edit(self, fields, wheres, returning):157 批量编辑数据库记录158 ### 拼接sql语句 ###159 #拼接字段与值160 field_list [key %( key )s for key infields.keys()]161 #设置sql拼接字典162 parameter {163 table_name: self.__table_name,164 pk_name: self.__pk_name,165 field_list: ,.join(field_list)166 }167 #如果存在更新条件则将条件添加到sql拼接更换字典中168 ifwheres:169 parameter[wheres] where wheres170 else:171 parameter[wheres] 172173 #如果有指定返回参数则添加174 ifreturning:175 parameter[returning] , returning176 else:177 parameter[returning] 178179 #生成sql语句180 sql update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s %parameter181 sql sql %fields182183 returnself.execute(sql)184185 def edit_model(self, pk, fields, wheres, returning):186 编辑单条数据库记录187 if notpk:188 return{}189 elifwheres:190 wheres self.__pk_name str(pk) and wheres191 else:192 wheres self.__pk_name str(pk)193194 returnself.edit(fields, wheres, returning)195196 def delete(self, wheres, returning, is_update_cacheTrue):197 批量删除数据库记录198 #如果存在条件199 ifwheres:200 wheres where wheres201202 #如果有指定返回参数则添加203 ifreturning:204 returning , returning205206 #生成sql语句207 sql delete from %(table_name)s %(wheres)s returning %(pk_name)s %(returning)s %\208 {table_name: self.__table_name, wheres: wheres, pk_name: self.__pk_name, returning: returning}209 returnself.execute(sql)210211 def delete_model(self, pk, wheres, returning, is_update_cacheTrue):212 删除单条数据库记录213 if notpk:214 return{}215 elifwheres:216 wheres self.__pk_name str(pk) and wheres217 else:218 wheres self.__pk_name str(pk)219220 returnself.delete(wheres, returning)221222 def get_list(self, column_name_list, wheres, page_numberNone, page_sizeNone, orderbyNone, table_nameNone):223 224 获取指定条件的数据库记录集225 :param column_name_list: 查询字段226 :param wheres: 查询条件227 :param page_number: 分页索引值228 :param page_size: 分页大小 存在值时才会执行分页229 :param orderby: 排序规则230 :param table_name: 查询数据表多表查询时需要设置231 :return: 返回记录集总数量与分页记录集232 {records: 0, total: 0, page: 0, rows: []}233 234 #初始化输出参数总记录数量与列表集235 data {236 records: 0, #总记录数237 total: 0, #总页数238 page: 1, #当前页面索引239 rows: [], #查询结果(记录列表)240 }241 #初始化查询数据表名称242 if nottable_name:243 table_name self.__table_name244 #初始化查询字段名245 if notcolumn_name_list:246 column_name_list self.__column_name_list247 #初始化查询条件248 ifwheres:249 #如果是字符串表示该查询条件已组装好了直接可以使用250 ifisinstance(wheres, str):251 wheres where wheres252 #如果是list则表示查询条件有多个可以使用join将它们用and方式组合起来使用253 elifisinstance(wheres, list):254 wheres where and.join(wheres)255 #初始化排序256 if notorderby:257 orderby self.__pk_name desc258 #初始化分页查询的记录区间259 paging 260261 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:262 #############################################################263 #判断是否需要进行分页264 if not page_size isNone:265 ### 执行sql获取指定条件的记录总数量266 sql select count(1) as records from %(table_name)s %(wheres)s %\267 {table_name: table_name, wheres: wheres}268 result db.execute(sql)269 #如果查询失败或不存在指定条件记录则直接返回初始值270 if not result or result[0][records] 0:271 returndata272273 #设置记录总数量274 data[records] result[0].get(records)275276 #########################################################277 ### 设置分页索引与页面大小 ###278 if page_size 0:279 page_size 10280 #计算总分页数量通过总记录数除于每页显示数量来计算总分页数量281 if data[records] % page_size 0:282 page_total data[records] //page_size283 else:284 page_total data[records] // page_size 1285 #判断页码是否超出限制超出限制查询时会出现异常所以将页面索引设置为最后一页286 if page_number 1 or page_number page_total:287 page_number page_total288 #记录总页面数量289 data[total] page_total290 #记录当前页面值291 data[page] page_number292 #计算当前页面要显示的记录起始位置(limit指定的位置)293 record_number (page_number - 1) *page_size294 #设置查询分页条件295 paging limit str(page_size) offset str(record_number)296 #############################################################297298 ### 按条件查询数据库记录299 sql select %(column_name_list)s from %(table_name)s %(wheres)s order by %(orderby)s %(paging)s %\300 {column_name_list: column_name_list,301 table_name: table_name,302 wheres: wheres,303 orderby: orderby,304 paging: paging}305 result db.execute(sql)306 ifresult:307 data[rows] result308 #不需要分页查询时直接在这里设置总记录数309 if page_size isNone:310 data[records] len(result)311312 returndata313314 def get_count(self, wheres):315 获取指定条件记录数量316 ifwheres:317 wheres where wheres318 sql select count(1) as total from %(table_name)s %(wheres)s %\319 {table_name: self.__table_name, wheres: wheres}320 result self.select(sql)321 #如果查询存在记录则返回true322 ifresult:323 return result[0].get(total)324 return0325326 defget_sum(self, fields, wheres):327 获取指定条件记录数量328 sql select sum(%(fields)s) as total from %(table_name)s where %(wheres)s %\329 {table_name: self.__table_name, wheres: wheres, fields: fields}330 result self.select(sql)331 #如果查询存在记录则返回true332 if result and result[0].get(total):333 return result[0].get(total)334 return0335336 defget_min(self, fields, wheres):337 获取该列记录最小值338 sql select min(%(fields)s) as min from %(table_name)s where %(wheres)s %\339 {table_name: self.__table_name, wheres: wheres, fields: fields}340 result self.select(sql)341 #如果查询存在记录则返回true342 if result and result[0].get(min):343 return result[0].get(min)344345 defget_max(self, fields, wheres):346 获取该列记录最大值347 sql select max(%(fields)s) as max from %(table_name)s where %(wheres)s %\348 {table_name: self.__table_name, wheres: wheres, fields: fields}349 result self.select(sql)350 #如果查询存在记录则返回true351 if result and result[0].get(max):352 return result[0].get(max)353354 #####################################################################View Code大家只要掌握了ORM简单的组合sql方法就可以自由发挥根据自己的需要去创建不同的方法了也可以随意更换mysql、mssql等数据库。当然这只是最简单的ORM方式提交字段参数和条件参数时它不会自动分辨字段的类型不会自动初始化默认值如果想让它变的更加强大还需要做更多的改造与处理这样做的话它也会跟着变的更加复杂和难懂性能也会跟着下降。不过当前功能对于多数项目来说已经足够使用了。大家如果有需要可以自行研究进行扩展。在日常操作中获取指定记录实体是最常见使用最频繁的操作为了减少对数据库的查询我们可以将ORM与Nosql结合起来提升ORM的操作性能当然如果你不想使用nosql缓存也可以直接跳过本章节。使用Nosql首先我们需要一个链接Nosql的配置文件用它来存储Nosql的服务地址、端口、密码等参数在config文件夹中我们创建redis_config.py配置文件#!/usr/bin/env python#codingutf-8### redis缓存配置参数 ###REDIS {#服务地址server: 127.0.0.1,#服务端口post: 6379,#服务密码pwd: ,#数据库序号db: 1}然后我们还需要一个nosql链接工具包(cache_helper.py)用来对nosql进行set、get、delete和clear操作(存储、获取、删除和清空缓存)1 #!/usr/bin/env python2 #codingutf-834 importredis56 from common importlog_helper7 from config importredis_config89 #设置redis配置参数10 _redis redis_config.REDIS11 #初始化Redis缓存链接12 r None13 try:14 if notr:15 r redis.Redis(host_redis.get(server, ),16 port_redis.get(post, ),17 db_redis.get(db, ),18 password_redis.get(pwd, ),19 socket_timeout1,20 socket_connect_timeout1)21 exceptException as e:22 log_helper.info(连接redis出错:( str(_redis) ) str(e.args))23 pass242526 def set(key, value, time86400):27 28 写缓存29 :param key: 缓存key字符串不区分大小写30 :param value: 要存储的值31 :param time: 缓存过期时间(单位秒)0永不过期32 :return:33 34 #将key转换为小写字母35 key str(key).lower()36 try:37 r.set(key, value, time)38 exceptException as e:39 log_helper.info(写缓存失败:key( key ) str(e.args))40 pass414243 defget(key):44 45 读缓存46 :param key: 缓存key字符串不区分大小写47 :return:48 49 #将key转换为小写字母50 key str(key).lower()51 try:52 value r.get(key)53 exceptException as e:54 #log_helper.error(读缓存失败:key( key ) str(e.args) r: str(r) _redis: str(_redis))55 value None5657 return_str_to_json(value)585960 defpush(key, value):61 62 添加数据到队列头部63 :param key: 缓存key字符串不区分大小写64 :param value: 要存储的值65 66 #将key转换为小写字母67 key str(key).lower()68 try:69 r.lpush(key, value)70 exceptException as e:71 log_helper.info(写缓存失败:key( key ) str(e.args))72 pass737475 defpop(key):76 77 从缓存队列的后尾读取一条数据78 :param key: 缓存key字符串不区分大小写79 :return: 缓存数据80 81 #将key转换为小写字母82 key str(key).lower()83 try:84 value r.rpop(key)85 exceptException as e:86 log_helper.info(读取缓存队列失败:key( key ) str(e.args))87 value None8889 return_str_to_json(value)909192 def_str_to_json(value):93 94 将缓存中读取出来的字符串转换成对应的数据、元组、列表或字典95 96 if notvalue:97 returnvalue98 #否则直接转换99 try:100 value value.decode()101 returneval(value)102 exceptException as e:103 print(e.args)104 pass105 #否则直接输出字符串106 returnvalue107108109 defdelete(key):110 111 删除缓存112 :param key:缓存key字符串不区分大小写113 :return:114 115 #将key转换为小写字母116 key str(key).lower()117 try:118 log_helper.info(str(r.delete(key)))119 exceptException as e:120 log_helper.info(Exception: str(e.args))121 pass122123124 defclear():125 126 清空所有缓存127 128 try:129 r.flushdb()130 except:131 passView Code我常用的是redis所以使用cache_helper.py时需要安装redis服务和对应的Python包。如果你使用的是memcache你只需要重构一下cache_helper.py代码就可以了。接下来我们改造一下逻辑层基类(ORM模块)首先我们需要导入cache_helperfrom common import db_helper, cache_helper在使用nosql缓存时大家都知道我们是使用key来进行对象存取的而这个key也是唯一的所以key的生成就很重要的为了避免key的重复我们在对记录设置key时可以用表名主键id的方式来组合key当然为了调用方便可以将获取key写成一个方法来生成defget_cache_key(self, pk):获取缓存key值return .join((self.__table_name, _, str(pk)))这里使用join的方法将表名、下横线、主键值组合生成缓存key字符串对于缓存的操作主要有设置缓存、获取缓存、删除缓存这三种操作当然为了方便我们获取记录中指定字段值我们可以增加读取指定字段值方法。首先是设置缓存方法大家看看下面代码它非常简单先调用生成缓存key然后将对象存储到缓存中并指定过期时间当设置time为0时它将永不过期def set_model_for_cache(self, pk, value, time43200):更新存储在缓存中的数据库记录缓存过期时间为12小时#生成缓存keykey self.get_cache_key(pk)#存储到nosql缓存中cache_helper.set(key, value, time)接着是获取缓存对象方法defget_model_for_cache(self, pk):从缓存中读取数据库记录#生成缓存keykey self.get_cache_key(pk)#从缓存中读取数据库记录result cache_helper.get(key)#缓存中不存在记录则从数据库获取if notresult:resultself.get_model_for_pk(pk)self.set_model_for_cache(pk, result)ifresult:returnresultelse:return {}我们首先要做的同样是生成缓存key然后调用get方法从缓存中读取对象执行完后需要判断该对象是否存在缓存中如果不存在则表示该对象并未存储到缓存中或它可能存储过期了所以需要重新从数据库中读取出来并将它存储到缓存中然后将读取出来的记录实体返回出去。然后我们再增加一个读取指定记录字段值的方法defget_value_for_cache(self, pk, column_name):获取指定记录的字段值return self.get_model_for_cache(pk).get(column_name)它直接调用获取缓存对象方法然后从返回的对象中读取指定的字段值就可以了删除缓存方法也很简单生成缓存key后直接调用delete进行删除。对于删除方法有时候调用不知是不是nosql自身bug问题还是在主从关系的nosql中读写分离会引起删除失败如果出现这种情况可以将delete改为set将该缓存set为空就可以解决这个问题defdel_model_for_cache(self, pk):删除缓存中指定数据#生成缓存keykey self.get_cache_key(pk)#log_helper.info(key)#存储到nosql缓存中cache_helper.delete(key)PS在使用缓存操作时有时我们直接对数据库进行操作就会引起数据与缓存不匹配出现脏数据的情况这时在后台增加清空缓存的操作直接调用cache_helper.clear()进行清空缓存。基本方法都完成了接下来就是要对ORM的删除与修改方法进行改造了让它们自行根据需要对缓存进行对应操作让缓存与数据表中的记录保持一致。在改造时我们只需要对删除与修改操作进行处理对新增与查询操作不需要操作因为新增的记录它并在缓存中并不存在所以不需要进行操作而查询也不会改变数据内容只有进行删除和修改操作时才会变动数据内容这时就需要更改缓存让数据保持一致。改造编辑记录实体方法1 def edit(self, fields, wheres, returning, is_update_cacheTrue):2 3 批量编辑数据库记录4 :param fields: 要更新的字段(字段名与值存储在字典中)5 :param wheres: 更新条件6 :param returning: 更新成功后返回的字段名7 :param is_update_cache: 是否同步更新缓存8 :return:9 10 ### 拼接sql语句 ###11 #拼接字段与值12 field_list [key %( key )s for key infields.keys()]13 #设置sql拼接字典14 parameter {15 table_name: self.__table_name,16 pk_name: self.__pk_name,17 field_list: ,.join(field_list)18 }19 #如果存在更新条件则将条件添加到sql拼接更换字典中20 ifwheres:21 parameter[wheres] where wheres22 else:23 parameter[wheres] 2425 #如果有指定返回参数则添加26 ifreturning:27 parameter[returning] , returning28 else:29 parameter[returning] 3031 #生成sql语句32 sql update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s %parameter33 sql sql %fields3435 result self.execute(sql)36 ifresult:37 #判断是否删除对应的缓存38 ifis_update_cache:39 #循环删除更新成功的所有记录对应的缓存40 for model inresult:41 self.del_model_for_cache(model.get(id, 0))42 return result大家可以看到该方法增加了is_update_cache 是否同步更新缓存参数这是因为我们在使用缓存时会存在一些特殊情况比如说批量更新很多数据时如果使用循环逐条清理对应缓存时会占用较多资源我们可以关掉缓存的同步更新直接调用clear清空所有缓存会更加快捷又比如说页面访问数的更新它会更新的非常频繁我们不需要实时清除可以使用其他方式触发清理也可以将点击数用独立缓存存储使用等而清理缓存我们只需要将缓存内容直接删除就可以了因为执行更新以后返回的记录实体没有设置为*时只返回主键id直接设置的话会造成缓存数据丢失细节的问题另外我们执行更新以后该记录也不一定还会被读取出来。删除记录也进行一样的改造1 def delete(self, wheres, returning, is_update_cacheTrue):2 3 批量删除数据库记录4 :param wheres: 删除条件5 :param returning: 删除成功后返回的字段名6 :param is_update_cache: 是否同步更新缓存7 :return:8 9 #如果存在条件10 ifwheres:11 wheres where wheres1213 #如果有指定返回参数则添加14 ifreturning:15 returning , returning1617 #生成sql语句18 sql delete from %(table_name)s %(wheres)s returning %(pk_name)s %(returning)s %\19 {table_name: self.__table_name, wheres: wheres, pk_name: self.__pk_name, returning: returning}20 result self.execute(sql)21 ifresult:22 #同步删除对应的缓存23 ifis_update_cache:24 for model inresult:25 self.del_model_for_cache(model.get(id, 0))26 return result对于缓存基本上就这两个要进行改造的操作了。在实现开发中我们认真想一想其实我们还会存在一些特殊的情况比如说我们对数据进行加工处理后将加工后的值存储到缓存中而对相关记录进行修改或删除操作以后由于这些缓存它与记录并没有关联所以执行相关操作以后它就变成孤岛不会实时同步产生脏数据。所以我们需要有一个功能可以将它们管理起来与该数据表的修改和删除操作关联起来进行修改和删除操作后同步清除这些特殊缓存。根据这些要求我们就需要再增加两个缓存操作方法用来存储这些特殊的缓存名称然后在进行修改和删除操作时同步清除这些特殊缓存。首先我们需要在初始化方法中添加一个绑定该数据表的全局缓存变量self.__cache_list它由表名称_cache_list组成。1 def __init__(self, db, is_output_sql, table_name, column_name_list*, pk_nameid):2 类初始化3 #数据库参数4 self.__db db5 #是否输出执行的Sql语句到日志中6 self.__is_output_sql is_output_sql7 #表名称8 self.__table_name str(table_name).lower()9 #查询的列字段名称*表示查询全部字段多于1个字段时用逗号进行分隔除了字段名外也可以是表达式10 self.__column_name_list str(column_name_list).lower()11 #主健名称12 self.__pk_name str(pk_name).lower()13 #缓存列表14 self.__cache_list self.__table_name _cache_list然后我们再添加特殊缓存存储方法1 defadd_relevance_cache_in_list(self, key):2 将缓存名称存储到列表里————主要存储与记录变更关联的3 #从nosql中读取全局缓存列表4 cache_list cache_helper.get(self.__cache_list)5 #判断缓存列表是否有值有则进行添加操作6 ifcache_list:7 #判断是否已存储列表中不存在则执行添加操作8 if not key incache_list:9 cache_list.append(key)10 cache_helper.set(self.__cache_list, cache_list)11 #无则直接创建全局缓存列表并存储到nosql中12 else:13 cache_list [key]14 cache_helper.set(self.__cache_list, cache_list)执行该方法会将我们自定义的缓存名称存储到全局缓存变量中接着我们再添加一个清除所有特殊缓存的方法1 defdel_relevance_cache(self):2 删除关联缓存————将和数据表记录关联的个性化缓存全部删除3 #从nosql中读取全局缓存列表4 cache_list cache_helper.get(self.__cache_list)5 #清除已删除缓存列表6 cache_helper.delete(self.__cache_list)7 ifcache_list:8 #执行删除操作9 for cache incache_list:10 cache_helper.delete(cache)添加完成以后我们再来改造一下修改与删除代码只需要在里面添加清除所有特殊缓存方法就可以了1 def edit(self, fields, wheres, returning, is_update_cacheTrue):2 3 批量编辑数据库记录4 :param fields: 要更新的字段(字段名与值存储在字典中)5 :param wheres: 更新条件6 :param returning: 更新成功后返回的字段名7 :param is_update_cache: 是否同步更新缓存8 :return:9 10 ### 拼接sql语句 ###11 #拼接字段与值12 field_list [key %( key )s for key infields.keys()]13 #设置sql拼接字典14 parameter {15 table_name: self.__table_name,16 pk_name: self.__pk_name,17 field_list: ,.join(field_list)18 }19 #如果存在更新条件则将条件添加到sql拼接更换字典中20 ifwheres:21 parameter[wheres] where wheres22 else:23 parameter[wheres] 2425 #如果有指定返回参数则添加26 ifreturning:27 parameter[returning] , returning28 else:29 parameter[returning] 3031 #生成sql语句32 sql update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s %parameter33 sql sql %fields3435 result self.execute(sql)36 ifresult:37 #判断是否删除对应的缓存38 ifis_update_cache:39 #循环删除更新成功的所有记录对应的缓存40 for model inresult:41 self.del_model_for_cache(model.get(id, 0))42 #同步删除与本表关联的缓存43 self.del_relevance_cache()44 returnresult4546 def delete(self, wheres, returning, is_update_cacheTrue):47 48 批量删除数据库记录49 :param wheres: 删除条件50 :param returning: 删除成功后返回的字段名51 :param is_update_cache: 是否同步更新缓存52 :return:53 54 #如果存在条件55 ifwheres:56 wheres where wheres5758 #如果有指定返回参数则添加59 ifreturning:60 returning , returning6162 #生成sql语句63 sql delete from %(table_name)s %(wheres)s returning %(pk_name)s %(returning)s %\64 {table_name: self.__table_name, wheres: wheres, pk_name: self.__pk_name, returning: returning}65 result self.execute(sql)66 ifresult:67 #同步删除对应的缓存68 ifis_update_cache:69 for model inresult:70 self.del_model_for_cache(model.get(id, 0))71 #同步删除与本表关联的缓存72 self.del_relevance_cache()73 return resultView CodeORM的缓存改造就全部完成了下面是完整代码1 #!/usr/bin/env python2 #codingutf-834 from common importdb_helper, cache_helper567 classLogicBase():8 逻辑层基础类910 def __init__(self, db, is_output_sql, table_name, column_name_list*, pk_nameid):11 类初始化12 #数据库参数13 self.__db db14 #是否输出执行的Sql语句到日志中15 self.__is_output_sql is_output_sql16 #表名称17 self.__table_name str(table_name).lower()18 #查询的列字段名称*表示查询全部字段多于1个字段时用逗号进行分隔除了字段名外也可以是表达式19 self.__column_name_list str(column_name_list).lower()20 #主健名称21 self.__pk_name str(pk_name).lower()22 #缓存列表23 self.__cache_list self.__table_name _cache_list2425 #####################################################################26 ### 执行Sql ###2728 defselect(self, sql):29 执行sql查询语句(select)30 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:31 #执行sql语句32 result db.execute(sql)33 if notresult:34 result []35 returnresult3637 defexecute(self, sql):38 执行sql语句并提交事务39 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:40 #执行sql语句41 result db.execute(sql)42 ifresult:43 db.commit()44 else:45 result []46 returnresult4748 defcopy(self, values, columns):49 批量更新数据50 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:51 #执行sql语句52 result db.copy(values, self.__table_name, columns)53 returnresult5455 defget_model(self, wheres):56 通过条件获取一条记录57 #如果有条件则自动添加where58 ifwheres:59 wheres where wheres6061 #合成sql语句62 sql select %(column_name_list)s from %(table_name)s %(wheres)s %\63 {column_name_list: self.__column_name_list, table_name: self.__table_name, wheres: wheres}64 #初化化数据库链接65 result self.select(sql)66 ifresult:67 returnresult[0]68 return{}6970 def get_model_for_pk(self, pk, wheres):71 通过主键值获取数据库记录实体72 if notpk:73 return{}74 #组装查询条件75 wheres %s %s % (self.__pk_name, str(pk))7677 returnself.get_model(wheres)7879 def get_value(self, column_name, wheres):80 81 获取指定条件的字段值————多于条记录时只取第一条记录82 :param column_name: 单个字段名如id83 :param wheres: 查询条件84 :return: 7 (指定的字段值)85 86 if notcolumn_name:87 returnNone88 elifwheres:89 wheres where wheres9091 sql select %(column_name)s from %(table_name)s %(wheres)s limit 1 %\92 {column_name: column_name, table_name: self.__table_name, wheres: wheres}93 result self.select(sql)94 #如果查询成功则直接返回记录字典95 ifresult:96 returnresult[0].get(column_name)9798 def get_value_list(self, column_name, wheres):99 100 获取指定条件记录的字段值列表101 :param column_name: 单个字段名如id102 :param wheres: 查询条件103 :return: [1,3,4,6,7]104 105 if notcolumn_name:106 column_name self.__pk_name107 elifwheres:108 wheres where wheres109110 sql select array_agg(%(column_name)s) as list from %(table_name)s %(wheres)s %\111 {column_name: column_name, table_name: self.__table_name, wheres: wheres}112 result self.select(sql)113 #如果查询失败或不存在指定条件记录则直接返回初始值114 if result andisinstance(result, list):115 return result[0].get(list)116 else:117 return[]118119 def add_model(self, fields, returning):120 新增数据库记录121 ### 拼接sql语句 ###122 #初始化变量123 key_list []124 value_list []125 #将传入的字典参数进行处理把字段名生成sql插入字段名数组和字典替换数组126 #PS:字符串使用字典替换参数时格式是%(name)s这里会生成对应的字串127 #比如128 #传入的字典为 {id: 1, name: 名称}129 #那么生成的key_list为id,name130 #而value_list为%(id)s,%(name)s131 #最终而value_list为字符串对应名称位置会被替换成相应的值132 for key infields.keys():133 key_list.append(key)134 value_list.append(%( key )s)135 #设置sql拼接字典并将数组(lit)使用join方式进行拼接生成用逗号分隔的字符串136 parameter {137 table_name: self.__table_name,138 pk_name: self.__pk_name,139 key_list: ,.join(key_list),140 value_list: ,.join(value_list)141 }142 #如果有指定返回参数则添加143 ifreturning:144 parameter[returning] , returning145 else:146 parameter[returning] 147148 #生成可以使用字典替换的字符串149 sql insert into %(table_name)s (%(key_list)s) values (%(value_list)s) returning %(pk_name)s %(returning)s %parameter150 #将生成好的字符串替字典参数值生成最终可执行的sql语句151 sql sql %fields152153 result self.execute(sql)154 ifresult:155 returnresult[0]156 return{}157158 def edit(self, fields, wheres, returning, is_update_cacheTrue):159 160 批量编辑数据库记录161 :param fields: 要更新的字段(字段名与值存储在字典中)162 :param wheres: 更新条件163 :param returning: 更新成功后返回的字段名164 :param is_update_cache: 是否同步更新缓存165 :return:166 167 ### 拼接sql语句 ###168 #拼接字段与值169 field_list [key %( key )s for key infields.keys()]170 #设置sql拼接字典171 parameter {172 table_name: self.__table_name,173 pk_name: self.__pk_name,174 field_list: ,.join(field_list)175 }176 #如果存在更新条件则将条件添加到sql拼接更换字典中177 ifwheres:178 parameter[wheres] where wheres179 else:180 parameter[wheres] 181182 #如果有指定返回参数则添加183 ifreturning:184 parameter[returning] , returning185 else:186 parameter[returning] 187188 #生成sql语句189 sql update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s %parameter190 sql sql %fields191192 result self.execute(sql)193 ifresult:194 #判断是否删除对应的缓存195 ifis_update_cache:196 #循环删除更新成功的所有记录对应的缓存197 for model inresult:198 self.del_model_for_cache(model.get(id, 0))199 #同步删除与本表关联的缓存200 self.del_relevance_cache()201 returnresult202203 def edit_model(self, pk, fields, wheres, returning):204 编辑单条数据库记录205 if notpk:206 return{}207 elifwheres:208 wheres self.__pk_name str(pk) and wheres209 else:210 wheres self.__pk_name str(pk)211212 returnself.edit(fields, wheres, returning)213214 def delete(self, wheres, returning, is_update_cacheTrue):215 216 批量删除数据库记录217 :param wheres: 删除条件218 :param returning: 删除成功后返回的字段名219 :param is_update_cache: 是否同步更新缓存220 :return:221 222 #如果存在条件223 ifwheres:224 wheres where wheres225226 #如果有指定返回参数则添加227 ifreturning:228 returning , returning229230 #生成sql语句231 sql delete from %(table_name)s %(wheres)s returning %(pk_name)s %(returning)s %\232 {table_name: self.__table_name, wheres: wheres, pk_name: self.__pk_name, returning: returning}233 result self.execute(sql)234 ifresult:235 #同步删除对应的缓存236 ifis_update_cache:237 for model inresult:238 self.del_model_for_cache(model.get(id, 0))239 #同步删除与本表关联的缓存240 self.del_relevance_cache()241 returnresult242243 def delete_model(self, pk, wheres, returning, is_update_cacheTrue):244 删除单条数据库记录245 if notpk:246 return{}247 elifwheres:248 wheres self.__pk_name str(pk) and wheres249 else:250 wheres self.__pk_name str(pk)251252 returnself.delete(wheres, returning)253254 def get_list(self, column_name_list, wheres, page_numberNone, page_sizeNone, orderbyNone, table_nameNone):255 256 获取指定条件的数据库记录集257 :param column_name_list: 查询字段258 :param wheres: 查询条件259 :param page_number: 分页索引值260 :param page_size: 分页大小 存在值时才会执行分页261 :param orderby: 排序规则262 :param table_name: 查询数据表多表查询时需要设置263 :return: 返回记录集总数量与分页记录集264 {records: 0, total: 0, page: 0, rows: []}265 266 #初始化输出参数总记录数量与列表集267 data {268 records: 0, #总记录数269 total: 0, #总页数270 page: 1, #当前页面索引271 rows: [], #查询结果(记录列表)272 }273 #初始化查询数据表名称274 if nottable_name:275 table_name self.__table_name276 #初始化查询字段名277 if notcolumn_name_list:278 column_name_list self.__column_name_list279 #初始化查询条件280 ifwheres:281 #如果是字符串表示该查询条件已组装好了直接可以使用282 ifisinstance(wheres, str):283 wheres where wheres284 #如果是list则表示查询条件有多个可以使用join将它们用and方式组合起来使用285 elifisinstance(wheres, list):286 wheres where and.join(wheres)287 #初始化排序288 if notorderby:289 orderby self.__pk_name desc290 #初始化分页查询的记录区间291 paging 292293 with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:294 #############################################################295 #判断是否需要进行分页296 if not page_size isNone:297 ### 执行sql获取指定条件的记录总数量298 sql select count(1) as records from %(table_name)s %(wheres)s %\299 {table_name: table_name, wheres: wheres}300 result db.execute(sql)301 #如果查询失败或不存在指定条件记录则直接返回初始值302 if not result or result[0][records] 0:303 returndata304305 #设置记录总数量306 data[records] result[0].get(records)307308 #########################################################309 ### 设置分页索引与页面大小 ###310 if page_size 0:311 page_size 10312 #计算总分页数量通过总记录数除于每页显示数量来计算总分页数量313 if data[records] % page_size 0:314 page_total data[records] //page_size315 else:316 page_total data[records] // page_size 1317 #判断页码是否超出限制超出限制查询时会出现异常所以将页面索引设置为最后一页318 if page_number 1 or page_number page_total:319 page_number page_total320 #记录总页面数量321 data[total] page_total322 #记录当前页面值323 data[page] page_number324 #计算当前页面要显示的记录起始位置(limit指定的位置)325 record_number (page_number - 1) *page_size326 #设置查询分页条件327 paging limit str(page_size) offset str(record_number)328 #############################################################329330 ### 按条件查询数据库记录331 sql select %(column_name_list)s from %(table_name)s %(wheres)s order by %(orderby)s %(paging)s %\332 {column_name_list: column_name_list,333 table_name: table_name,334 wheres: wheres,335 orderby: orderby,336 paging: paging}337 result db.execute(sql)338 ifresult:339 data[rows] result340 #不需要分页查询时直接在这里设置总记录数341 if page_size isNone:342 data[records] len(result)343344 returndata345346 def get_count(self, wheres):347 获取指定条件记录数量348 ifwheres:349 wheres where wheres350 sql select count(1) as total from %(table_name)s %(wheres)s %\351 {table_name: self.__table_name, wheres: wheres}352 result self.select(sql)353 #如果查询存在记录则返回true354 ifresult:355 return result[0].get(total)356 return0357358 defget_sum(self, fields, wheres):359 获取指定条件记录数量360 sql select sum(%(fields)s) as total from %(table_name)s where %(wheres)s %\361 {table_name: self.__table_name, wheres: wheres, fields: fields}362 result self.select(sql)363 #如果查询存在记录则返回true364 if result and result[0].get(total):365 return result[0].get(total)366 return0367368 defget_min(self, fields, wheres):369 获取该列记录最小值370 sql select min(%(fields)s) as min from %(table_name)s where %(wheres)s %\371 {table_name: self.__table_name, wheres: wheres, fields: fields}372 result self.select(sql)373 #如果查询存在记录则返回true374 if result and result[0].get(min):375 return result[0].get(min)376377 defget_max(self, fields, wheres):378 获取该列记录最大值379 sql select max(%(fields)s) as max from %(table_name)s where %(wheres)s %\380 {table_name: self.__table_name, wheres: wheres, fields: fields}381 result self.select(sql)382 #如果查询存在记录则返回true383 if result and result[0].get(max):384 return result[0].get(max)385386 #####################################################################387388389 #####################################################################390 ### 缓存操作方法 ###391392 defget_cache_key(self, pk):393 获取缓存key值394 return .join((self.__table_name, _, str(pk)))395396 def set_model_for_cache(self, pk, value, time43200):397 更新存储在缓存中的数据库记录缓存过期时间为12小时398 #生成缓存key399 key self.get_cache_key(pk)400 #存储到nosql缓存中401 cache_helper.set(key, value, time)402403 defget_model_for_cache(self, pk):404 从缓存中读取数据库记录405 #生成缓存key406 key self.get_cache_key(pk)407 #从缓存中读取数据库记录408 result cache_helper.get(key)409 #缓存中不存在记录则从数据库获取410 if notresult:411 result self.get_model_for_pk(pk)412 self.set_model_for_cache(pk, result)413 ifresult:414 returnresult415 else:416 return{}417418 defget_value_for_cache(self, pk, column_name):419 获取指定记录的字段值420 returnself.get_model_for_cache(pk).get(column_name)421422 defdel_model_for_cache(self, pk):423 删除缓存中指定数据424 #生成缓存key425 key self.get_cache_key(pk)426 #log_helper.info(key)427 #存储到nosql缓存中428 cache_helper.delete(key)429430 defadd_relevance_cache_in_list(self, key):431 将缓存名称存储到列表里————主要存储与记录变更关联的432 #从nosql中读取全局缓存列表433 cache_list cache_helper.get(self.__cache_list)434 #判断缓存列表是否有值有则进行添加操作435 ifcache_list:436 #判断是否已存储列表中不存在则执行添加操作437 if not key incache_list:438 cache_list.append(key)439 cache_helper.set(self.__cache_list, cache_list)440 #无则直接创建全局缓存列表并存储到nosql中441 else:442 cache_list [key]443 cache_helper.set(self.__cache_list, cache_list)444445 defdel_relevance_cache(self):446 删除关联缓存————将和数据表记录关联的个性化缓存全部删除447 #从nosql中读取全局缓存列表448 cache_list cache_helper.get(self.__cache_list)449 #清除已删除缓存列表450 cache_helper.delete(self.__cache_list)451 ifcache_list:452 #执行删除操作453 for cache incache_list:454 cache_helper.delete(cache)455456 #####################################################################View Code版权声明本文原创发表于 博客园作者为python开发QQ群669058475(本群已满)、733466321(可以加2群) 作者博客http://www.cnblogs.com/EmptyFS/