接口代码重构,web开垦框架

  前边O昂科威M模块我们早就到位了开荒,接下去要做的正是对项目代码实行重构了。因为对底层数据库操作模块(db_helper.py)进行了退换,以前项指标接口代码全都跑不起来了。

  多少个复杂的O奥迪Q五M方式都已介绍完了,剩下部分常用的删除、获取记录数据、总计合计数、获取最大值、获取最小值等措施自身就不1一详细介绍了,直接付出代码大家自行查看。

  后边的菜系、部门、职位与领队保管功效实现后,接下去要处理的是将它们关联起来,依照职务管理中选定的权能决定菜单彰显以及页面数据的造访和操作。

  在上一章中,我们已经创办好OBMWX伍M的基类了,接下去要做的就是将基类的常用方法1一落成。

  在写O宝马7系M模块时,大家曾经对产品接口的分页查询、新增添、修改、获取钦定产品实业接口已经重构好了,还剩余删除接口未到位

澳门葡京备用网址 1澳门葡京备用网址 2

  那么要怎么退换呢?大家得以经过用户的操作步骤来一步步开始展览拍卖,具体思路如下:

  首先大家来看看前边项目中,最常见的收获钦点主键的记录实体

 1 @delete('/api/product/<id:int>/')
 2 def callback(id):
 3     """
 4     删除指定记录
 5     """
 6     # 编辑记录
 7     sql = """delete from product where id=%s returning id"""
 8     vars = (id,)
 9     # 写入数据库
10     result = db_helper.write(sql, vars)
11     # 判断是否提交成功
12     if result:
13         return web_helper.return_msg(0, '成功')
14     else:
15         return web_helper.return_msg(-1, "删除失败")
  1 #!/usr/bin/env python
  2 # coding=utf-8
  3 
  4 from common import db_helper
  5 
  6 
  7 class LogicBase():
  8     """逻辑层基础类"""
  9 
 10     def __init__(self, db, is_output_sql, table_name, column_name_list='*', pk_name='id'):
 11         """类初始化"""
 12         # 数据库参数
 13         self.__db = db
 14         # 是否输出执行的Sql语句到日志中
 15         self.__is_output_sql = is_output_sql
 16         # 表名称
 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     #####################################################################
 24     ### 执行Sql ###
 25 
 26     def select(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 not result:
 32                 result = []
 33         return result
 34 
 35     def execute(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             if result:
 41                 db.commit()
 42             else:
 43                 result = []
 44         return result
 45 
 46     def copy(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         return result
 52 
 53     def get_model(self, wheres):
 54         """通过条件获取一条记录"""
 55         # 如果有条件,则自动添加where
 56         if wheres:
 57             wheres = ' where ' + wheres
 58 
 59         # 合成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         if result:
 65             return result[0]
 66         return {}
 67 
 68     def get_model_for_pk(self, pk, wheres=''):
 69         """通过主键值获取数据库记录实体"""
 70         if not pk:
 71             return {}
 72         # 组装查询条件
 73         wheres = '%s = %s' % (self.__pk_name, str(pk))
 74 
 75         return self.get_model(wheres)
 76 
 77     def get_value(self, column_name, wheres=''):
 78         """
 79         获取指定条件的字段值————多于条记录时,只取第一条记录
 80         :param column_name: 单个字段名,如:id
 81         :param wheres: 查询条件
 82         :return: 7 (指定的字段值)
 83         """
 84         if not column_name:
 85             return None
 86         elif wheres:
 87             wheres = ' where ' + wheres
 88 
 89         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         if result:
 94             return result[0].get(column_name)
 95 
 96     def get_value_list(self, column_name, wheres=''):
 97         """
 98         获取指定条件记录的字段值列表
 99         :param column_name: 单个字段名,如:id
100         :param wheres: 查询条件
101         :return: [1,3,4,6,7]
102         """
103         if not column_name:
104             column_name = self.__pk_name
105         elif wheres:
106             wheres = ' where ' + wheres
107 
108         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 and isinstance(result, list):
113             return result[0].get('list')
114         else:
115             return []
116 
117     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','name'
128         #   而value_list为:'%(id)s,%(name)s'
129         #   最终而value_list为字符串对应名称位置会被替换成相应的值
130         for key in fields.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         if returning:
142             parameter['returning'] = ', ' + returning
143         else:
144             parameter['returning'] = ''
145 
146         # 生成可以使用字典替换的字符串
147         sql = "insert into %(table_name)s (%(key_list)s) values (%(value_list)s) returning %(pk_name)s %(returning)s" % parameter
148         # 将生成好的字符串替字典参数值,生成最终可执行的sql语句
149         sql = sql % fields
150 
151         result = self.execute(sql)
152         if result:
153             return result[0]
154         return {}
155 
156     def edit(self, fields, wheres='', returning=''):
157         """批量编辑数据库记录"""
158         ### 拼接sql语句 ###
159         # 拼接字段与值
160         field_list = [key + ' = %(' + key + ')s' for key in fields.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         if wheres:
169             parameter['wheres'] = ' where ' + wheres
170         else:
171             parameter['wheres'] = ''
172 
173         # 如果有指定返回参数,则添加
174         if returning:
175             parameter['returning'] = ', ' + returning
176         else:
177             parameter['returning'] = ''
178 
179         # 生成sql语句
180         sql = "update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s" % parameter
181         sql = sql % fields
182 
183         return self.execute(sql)
184 
185     def edit_model(self, pk, fields, wheres='', returning=''):
186         """编辑单条数据库记录"""
187         if not pk:
188             return {}
189         elif wheres:
190             wheres = self.__pk_name + ' = ' + str(pk) + ' and ' + wheres
191         else:
192             wheres = self.__pk_name + ' = ' + str(pk)
193 
194         return self.edit(fields, wheres, returning)
195 
196     def delete(self, wheres='', returning='', is_update_cache=True):
197         """批量删除数据库记录"""
198         # 如果存在条件
199         if wheres:
200             wheres = ' where ' + wheres
201 
202         # 如果有指定返回参数,则添加
203         if returning:
204             returning = ', ' + returning
205 
206         # 生成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         return self.execute(sql)
210 
211     def delete_model(self, pk, wheres='', returning='', is_update_cache=True):
212         """删除单条数据库记录"""
213         if not pk:
214             return {}
215         elif wheres:
216             wheres = self.__pk_name + ' = ' + str(pk) + ' and ' + wheres
217         else:
218             wheres = self.__pk_name + ' = ' + str(pk)
219 
220         return self.delete(wheres, returning)
221 
222     def get_list(self, column_name_list='', wheres='', page_number=None, page_size=None, orderby=None, table_name=None):
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 not table_name:
243             table_name = self.__table_name
244         # 初始化查询字段名
245         if not column_name_list:
246             column_name_list = self.__column_name_list
247         # 初始化查询条件
248         if wheres:
249             # 如果是字符串,表示该查询条件已组装好了,直接可以使用
250             if isinstance(wheres, str):
251                 wheres = 'where ' + wheres
252             # 如果是list,则表示查询条件有多个,可以使用join将它们用and方式组合起来使用
253             elif isinstance(wheres, list):
254                 wheres = 'where ' + ' and '.join(wheres)
255         # 初始化排序
256         if not orderby:
257             orderby = self.__pk_name + ' desc'
258         # 初始化分页查询的记录区间
259         paging = ''
260 
261         with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:
262             #############################################################
263             # 判断是否需要进行分页
264             if not page_size is None:
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                     return data
272 
273                 # 设置记录总数量
274                 data['records'] = result[0].get('records')
275 
276                 #########################################################
277                 ### 设置分页索引与页面大小 ###
278                 if page_size <= 0:
279                     page_size = 10
280                 # 计算总分页数量:通过总记录数除于每页显示数量来计算总分页数量
281                 if data['records'] % page_size == 0:
282                     page_total = data['records'] // page_size
283                 else:
284                     page_total = data['records'] // page_size + 1
285                 # 判断页码是否超出限制,超出限制查询时会出现异常,所以将页面索引设置为最后一页
286                 if page_number < 1 or page_number > page_total:
287                     page_number = page_total
288                 # 记录总页面数量
289                 data['total'] = page_total
290                 # 记录当前页面值
291                 data['page'] = page_number
292                 # 计算当前页面要显示的记录起始位置(limit指定的位置)
293                 record_number = (page_number - 1) * page_size
294                 # 设置查询分页条件
295                 paging = ' limit ' + str(page_size) + ' offset ' + str(record_number)
296             #############################################################
297 
298             ### 按条件查询数据库记录
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             if result:
307                 data['rows'] = result
308                 # 不需要分页查询时,直接在这里设置总记录数
309                 if page_size is None:
310                     data['records'] = len(result)
311 
312         return data
313 
314     def get_count(self, wheres=''):
315         """获取指定条件记录数量"""
316         if wheres:
317             wheres = ' where ' + wheres
318         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         # 如果查询存在记录,则返回true
322         if result:
323             return result[0].get('total')
324         return 0
325 
326     def get_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         # 如果查询存在记录,则返回true
332         if result and result[0].get('total'):
333             return result[0].get('total')
334         return 0
335 
336     def get_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         # 如果查询存在记录,则返回true
342         if result and result[0].get('min'):
343             return result[0].get('min')
344 
345     def get_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         # 如果查询存在记录,则返回true
351         if result and result[0].get('max'):
352             return result[0].get('max')
353 
354             #####################################################################

  一.用户在管理端登陆时,通过用户记录所绑定的地点新闻,来规定用户所负有的权限。大家得以在登入接口中,将该管理员的职位id存款和储蓄到session中,以便于后续的调用。

@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, "查询失败")

  假若前方代码有认真学习的伴儿看到那段代码,要改成OCR-VM格局应该很轻松达成了

View Code

  贰.登入成功后,跳转进去管理界口,在得到菜单列表时,要求对菜单列表实行拍卖,只列出脚下用户有权力的菜单项。

  从代码中能够看出,大家须求进行select
* from product where id = xx从数据表中询问到大家想要的数量。

  只须求将第十行到第柒行替换对应的调用代码就足以了

 

  三.在点击菜单进入相关数据页面或在数额页面举行增加和删除改查等操作时,须要实行权力判别,判定是还是不是有权力进行查看或操作。由于大家是内外端分离,所以权限只须要在接口举行处理。

  要封装成O昂CoraM的秘诀,笔者急需须求小心上面几项业务:

 1 @delete('/api/product/<id:int>/')
 2 def callback(id):
 3     """
 4     删除指定记录
 5     """
 6     # 实例化product表操作类ProductLogic
 7     _product_logic = product_logic.ProductLogic()
 8     result = _product_logic.delete_model(id)
 9     # 判断是否提交成功
10     if result:
11         return web_helper.return_msg(0, '成功')
12     else:
13         return web_helper.return_msg(-1, "删除失败")

  大家只要驾驭了O中华VM轻松的构成sql方法,就能够自由发挥,依照本人的供给去创建差异的法子了,也得以随便改换mysql、mssql等数据库。

  首先大家来简单改换一下签到接口login.py,只必要在将地方id存款和储蓄到session中就足以了

  一.方法名必须是归纳易懂的

  首先是初叶化产品逻辑层操作类,然后调用delete_model()这些方式就足以了

  当然,那只是最简便的O帕杰罗M格局,提交字段参数和标准化参数时,它不会自行辨识字段的品类,不会自动伊始化暗许值,假若想让它变的一发强硬,还亟需做愈来愈多的改建与处理,那样做的话它也会随着变的越来越错综复杂和难懂,质量也会随之下落。可是当下成效对于大大多品种以来,已经够用使用了。我们就算有需求能够自动钻研举办扩充。

1     ##############################################################2     ### 把用户信息保存到session中 ###3     ##############################################################4     manager_id = manager_result.get('id', 0)5     s['id'] = manager_id6     s['login_name'] = username7     s['positions_id'] = manager_result.get('positions_id', '')8     s.save()

  贰.主意必要吸收钦命的主键值

  当您见惯不惊那种写法以往,你会意识达成种种接口会变得拾叁分的粗略与福利,开辟进度比此前也晋级了重重

 

  找到地点内容,在个中插入
s[‘positions_id’] = manager_result.get(‘positions_id’, ”)

  三.sql亟待在措施中张开组装

  产品分类有关接口(product_class.py)与产品有关接口(product.py)作用差不多,具体落到实处小编就不一一解说了,我们能够协调尝试

  在平凡操作中,获取内定记录实体是最普遍使用最频仍的操作,为了削减对数据库的询问,大家能够将O本田UR-VM与Nosql结合起来,升高O揽胜极光M的操作性能,当然如若您不想行使nosql缓存,也得以直接跳过本章节。

  接下去更换菜单列表接口menu_info.py文件的@get(‘/api/main/menu_info/’)接口,大家须要做以下操作:

  依据那几个须求,大家能够很轻松写出那些法子

 

  使用Nosql,首先大家供给二个链接Nosql的布局文件,用它来存款和储蓄Nosql的劳务地点、端口、密码等参数

  壹.第二从session中收获当前用户的职责id,然后根据职分id从任务表中读取对应的权能数据

    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

  产品分类的删除分类接口我们会看出它的代码与制品删除接口大约,然则多了3个该分类是不是早已被引述的2个论断,对于那几个上边专门求证一下

  在config文件夹中我们成立redis_config.py配置文件

  2.其次在菜单的遍历组装进度中,增添判定用户的权能,未有权力的菜单项直接过滤掉

  大家经过艺术名(get_model_for_pk)应当能够清楚,我们是经过主键来获取内定的记录实体内容。

 1 @delete('/api/product_class/<id:int>/')
 2 def callback(id):
 3     """
 4     删除指定记录
 5     """
 6     # 判断该分类是否已经被引用,是的话不能直接删除
 7     sql = """select count(*) as total from product where product_class_id=%s""" % (id,)
 8     # 读取记录
 9     result = db_helper.read(sql)
10     if result and result[0].get('total', -1) > 0:
11         return web_helper.return_msg(-1, "该分类已被引用,请清除对该分类的绑定后再来删除")
12 
13     # 编辑记录
14     sql = """delete from product_class where id=%s returning id"""
15     vars = (id,)
16     # 写入数据库
17     result = db_helper.write(sql, vars)
18     # 判断是否提交成功
19     if result:
20         return web_helper.return_msg(0, '成功')
21     else:
22         return web_helper.return_msg(-1, "删除失败")
#!/usr/bin/env python
# coding=utf-8

### redis缓存配置参数 ###
REDIS = {
    # 服务地址
    'server': '127.0.0.1',
    # 服务端口
    'post': 6379,
    # 服务密码
    'pwd': '',
    # 数据库序号
    'db': 1
}
 1 @get('/api/main/menu_info/') 2 def callback(): 3     """ 4     主页面获取菜单列表数据 5     """ 6     # 获取当前用户权限 7     session = web_helper.get_session() 8     if session: 9         _positions_logic = positions_logic.PositionsLogic()10         page_power = _positions_logic.get_page_power(session.get('positions_id'))11     else:12         page_power = ''13     if not page_power:14         return web_helper.return_msg(-404, '您的登录已超时,请重新登录')15 16     _menu_info_logic = menu_info_logic.MenuInfoLogic()17     # 读取记录18     result = _menu_info_logic.get_list('*', 'is_show and is_enabled', orderby='sort')19     if result:20         # 定义最终输出的html存储变量21         html = ''22         for model in result.get('rows'):23             # 检查是否有权限24             if ',' + str(model.get('id')) + ',' in page_power:25                 # 提取出第一级菜单26                 if model.get('parent_id') == 0:27                     # 添加一级菜单28                     temp = """29                     <dl >30                         <dt><i >%s</i> %s<i >&#xe6d5;</i></dt>31                         <dd>32                             <ul>33                     """ % {'id': model.get('id'), 'icon': model.get('icon'), 'name': model.get('name')}34                     html = html + temp35 36                     # 从所有菜单记录中提取当前一级菜单下的子菜单37                     for sub_model in result.get('rows'):38                         # 检查是否有权限39                         if ',' + str(sub_model.get('id')) + ',' in page_power:40                             # 如果父id等于当前一级菜单id,则为当前菜单的子菜单41                             if sub_model.get('parent_id') == model.get('id'):42                                 temp = """43                                 <li><a data-href="%s" data-title="%s" href="javascript:void">%s</a></li>44                             """ % {'page_url': sub_model.get('page_url'), 'name': sub_model.get('name')}45                                 html = html + temp46     47                     # 闭合菜单html48                     temp = """49                             </ul>50                         </dd>51                     </dl>52                         """53                     html = html + temp54 55         return web_helper.return_msg(0, '成功', {'menu_html': html})56     else:57         return web_helper.return_msg(-1, "查询失败")

  该办法需求传入的参数值是主键值pk

  那段代码后半部分能够参考产品的删除接口完结,前半有的必要调用产品艺术开始展览决断处理。

  然后大家还亟需一个nosql链接工具包(cache_helper.py),用来对nosql实行set、get、delete和clear操作(存款和储蓄、获取、删除和清空缓存)

  第十与第十行,便是从岗位表中,读取钦命地点id的权能page_power字段值,第3四行与第3玖行中,只须求决断当前菜谱id是还是不是留存page_power字段值中,就足以看清是还是不是具备该菜单权限了,因为在前头位置管理那里,勾选了钦点菜单id后,就会将菜单的id存款和储蓄到那一个字段中。

  在吸收接纳到主健值以往,大家需求对它举行简短的论断处理,假设它为空则直接回到空字典。

  在编排时大家会意识,大家的ORubiconM并从未直接决断记录是还是不是留存的主意,唯有2个用于获取钦赐条件记录数的秘技。

澳门葡京备用网址 3澳门葡京备用网址 4

  由于大概多处索要读取权限page_power字段值,那里大家需求在地点逻辑类positions_logic.py中添加get_page_power()方法,来收获其值出来使用。

  在整合sql前,大家需求选对查询条件举办组装,那里我们直接利用self.__pk_接口代码重构,web开垦框架。name,在上一章初叶化时定义好的私下认可项,在那边不直接使用id做为条件字段,是为了当出现主键名叫别的字符时,可以灵活处理。比如订单表使用code为主键时,就能够直接绑定code而不是自增id了。比如self.__pk_name初叶值是id,主键pk值是一,那么组装后的查询条件为
id=一

  一般的话,大家在支付时发现OSportageM未有本身想要的主意时,大家必要做以下驰念:

  1 #!/usr/bin/env python
  2 # coding=utf-8
  3 
  4 import redis
  5 
  6 from common import log_helper
  7 from config import redis_config
  8 
  9 # 设置redis配置参数
 10 _redis = redis_config.REDIS
 11 # 初始化Redis缓存链接
 12 r = None
 13 try:
 14     if not r:
 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_timeout=1,
 20                         socket_connect_timeout=1)
 21 except Exception as e:
 22     log_helper.info('连接redis出错:(' + str(_redis) + ')' + str(e.args))
 23     pass
 24 
 25 
 26 def set(key, value, time=86400):
 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     except Exception as e:
 39         log_helper.info('写缓存失败:key(' + key + ')' + str(e.args))
 40         pass
 41 
 42 
 43 def get(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     except Exception as e:
 54         # log_helper.error('读缓存失败:key(' + key + ')' + str(e.args) + ' r:' + str(r) + ' _redis:' + str(_redis))
 55         value = None
 56 
 57     return _str_to_json(value)
 58 
 59 
 60 def push(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     except Exception as e:
 71         log_helper.info('写缓存失败:key(' + key + ')' + str(e.args))
 72         pass
 73 
 74 
 75 def pop(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     except Exception as e:
 86         log_helper.info('读取缓存队列失败:key(' + key + ')' + str(e.args))
 87         value = None
 88 
 89     return _str_to_json(value)
 90 
 91 
 92 def _str_to_json(value):
 93     """
 94     将缓存中读取出来的字符串转换成对应的数据、元组、列表或字典
 95     """
 96     if not value:
 97         return value
 98     # 否则直接转换
 99     try:
100         value = value.decode()
101         return eval(value)
102     except Exception as e:
103         print(e.args)
104         pass
105     # 否则直接输出字符串
106     return value
107 
108 
109 def delete(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     except Exception as e:
120         log_helper.info('Exception:' + str(e.args))
121         pass
122 
123 
124 def clear():
125     """
126     清空所有缓存
127     """
128     try:
129         r.flushdb()
130     except:
131         pass
1     def get_page_power(self, positions_id):2         """获取当前用户权限"""3         page_power = self.get_value_for_cache(positions_id, 'page_power')4         if page_power:5             return ',' + page_power + ','6         else:7             return ','

  然后一贯调用暗中同意项查询字段名称self.__column_name_list和表名称self.__table_name来合成sql语句。例如self.__column_name_list起先值为*,self.__table_name早先值为product,那么合成的sql语句为:select
* from product where id=1

  一.有未有顶替能够达成的艺术存在

View Code

  大家调用OCRUISERM的get_value_for_cache()方法,直接通过主键id来读取大家想要的字段值,并在权力字串两端增加逗号,因为我们在可比菜单id是或不是留存于权力字串时,不增加逗号大概会出错,比如说权限串有2,10,11,假设大家直接相比一是否存在于权力串中,借使不转为list,直接字符串比较,再次来到结果就会为True,因为十和1一都留存一,而各扩展逗号今后比较就分裂等了,,二,10,11,与,一,相比较一定回来的是False,也正是说当前管理员未有具有壹这一个菜单id的权能。

  最后调用数据库操作类db_helper来推行sql语句(那里运用widh方法来初步化数据库操作类),将进行后的结果再次回到主程序

  二.该作用是不是是常用的成效,能不可能封装成公共艺术,假如得以就将它包裹到逻辑层基类(ORAV4M模块)中去,让具有继续的子类都存有这些作用

  笔者常用的是redis,所以利用cache_helper.py时,供给安装redis服务和对应的Python包。假使您使用的是memcache,你只须求重构一下cache_helper.py代码就能够了。

  PS:实现菜单列表作用的改动后,记得检查菜单列表页面(main.html)和改动的接口是否在上1章节截至后,增多到菜单管理项中,并在地点管理中将相应的权位项打上勾,若是未有的话,完费用文字改正造,登6后台将会提醒您从未访问权限。

 

  三.比方它只是对点名表单操作时才用到,就将它包裹到该逻辑层子类,方便该子类要用到时得以每一日调用

  接下去大家退换一下逻辑层基类(O科雷傲M模块)

  最终要拍卖的是后台管理各接口的权能推断,由于bottle勾子(@hook(‘before_request’))直接获取当前访问的路由,所取获得的都有具体值(比如:@get(‘/system/menu_info/<id:int>/’)
那些路由,在勾子中取到的是/system/menu_info/1/,
由于id值是不牢固的,大家要处理起来会很麻),所以大家只可以在各样接口中央直机关接处理,约等于说大家须求在每一个接口中,增多固定的权能推断方法调用。

  针对地方这几个读取产品记录实体的功用,大家像上一章同样,先创立好二个产品质量管理理理的逻辑类,承继OLacrosseM基类

  那段代码的必要是推断钦定的分类是不是被产品引用,抽象出来的情致正是判别内定条件的记录是或不是留存,对于那么些效应有开采经历的同伙很轻便看清它是众多地方都有希望要用到的通用方法,所以大家要求在O奇骏M中追加一下以此措施。而小编辈OBMWX三M已经存在get_count()这些获得记录数的艺术存在了,大家得以由此调用那一个主意来判别记录数据是或不是大于0,来得出钦定条件的笔录是或不是存在那样的结果。

  首先大家须求导入cache_helper

  而权力的处理须求对数据库对数据库举行读取操作,所以我们得以在逻辑层文件夹中增添二个通用的逻辑层模块_common_logic.py,将权限决断方式在那么些文件中贯彻,方便调用。

#!/usr/bin/env python
# coding=utf-8

from logic import _logic_base
from config import db_config


class 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)
    def exists(self, wheres):
        """检查指定条件的记录是否存在"""
        return self.get_count(wheres) > 0
from common import db_helper, cache_helper

  那里的权杖推断完结原理是:通过获取web来路html页面名称、当前接口访问格局、当前拜会的接口路由名称,将它们构成3个key值,从菜系权限开首化缓存中读抽出对应的菜系实体(前边会讲到怎样生成那些菜单权限缓存),提取当前所走访接口所对应的菜单id值,然后通过从session中收获当前用户的义务id,获取当前用户所怀有的职位权限,将菜单id与地点权限进行比较,剖断用户是或不是具备近年来所访问的接口权限,从而落成对权力的访问调整。

  大家就足以一贯退换后面包车型客车接口调用代码了

  有了那一个法子,大家就可以一连对产品分类删除接口进行改换了

  在使用nosql缓存时,大家都知晓大家是使用key来实行对象存取的,而以此key也是绝无仅有的,所以key的生成就很重大的,为了防止key的重复,大家在对记录设置key时,能够用表名+主键id的法子来整合key,当然为了调用方便,能够将获得key写成2个方法来变化

  具体贯彻那么些权力决断方式,有以下步骤:

@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 @delete('/api/product_class/<id:int>/')
 2 def callback(id):
 3     """
 4     删除指定记录
 5     """
 6     # 实例化product表操作类ProductLogic
 7     _product_logic = product_logic.ProductLogic()
 8     # 判断该分类是否已经被引用,是的话不能直接删除
 9     if _product_logic.exists('product_class_id=' + str(id)):
10         return web_helper.return_msg(-1, "该分类已被引用,请清除对该分类的绑定后再来删除")
11 
12     # 实例化product_class表操作类product_class_logic
13     _product_class_logic = product_class_logic.ProductClassLogic()
14     result = _product_class_logic.delete_model(id)
15     # 判断是否提交成功
16     if result:
17         return web_helper.return_msg(0, '成功')
18     else:
19         return web_helper.return_msg(-1, "删除失败")
    def get_cache_key(self, pk):
        """获取缓存key值"""
        return ''.join((self.__table_name, '_', str(pk)))

  1.首先我们供给取得web的来头地址HTTP_REFERE路虎极光,由于大家在方今菜单管理中,录入的html页面地址不包蕴域名和参数,所以来路地址须求去掉当前域名和?号前面包车型地铁叠加参数,只保留html页面名称。

  和日前的代码比较,代码看起来大约多了

  通过这么些事例,我们在实际上开荒进度中,能够灵活的依照本身需求,来增添或改建对应的平底方法,积累你自身的平底框架代码,那么随着开采时间的增添,你付出起种种成效来就会越加百步穿杨了。

  那里运用join的方法,将表名、下横线、主键值组合生成缓存key字符串

  2.直接从从bottle的request中,读取当前作客接口的路由值

  直接上单元测试看看实践遵从

 

 

  三.从bottle的request中拿走当前作客接口的方法(get/post/put/delete)

 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表操作类ProductLogic
23         _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()

  细心的对象会发觉,O宝马7系M模块的缓存部分,多了三个get_model_for_cache_of_where()方法,上面笔者来验证一下它的用途。

  对于缓存的操作,首要有设置缓存、获取缓存、删除缓存那三种操作,当然为了方便我们赢得记录中钦赐字段值,我们得以追加读取钦赐字段值方法。

  4.将前方三步获取的值组合成菜单对应的绝无仅有key,然后在菜单权限缓存中读取对应的菜单实体

  输出结果:

  大家在开荒时,除了通过主键id来博取记录实体以外,在局地数据表中,还会存在第三个主键,或七个主键的意况,大家须求经过这么些主键来获得相应的记录实休,比如说管理员或用户表中的记名账号字段;订单表中的订单编码字段等。

  首先是设置缓存方法,大家看看上面代码,它至极轻松,先调用生成缓存key,然后将目的存款和储蓄到缓存中,并点名过期时间,当设置time为0时,它将毫可是期

  5.假诺菜单记录实体不设有,则发挥当前接口未注册或注册时所提交的新闻错误,当前用户并未该接口的访问权限

------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------

  平常意况下,大家直接通过get_model()方法就足以读取对应的记录了,假使我们想减掉数据库的询问,直接在缓存中如何行使呢?直接存取记录实体,由于那么些额外的主键并未与ORAV四M中的编辑与删除操作关联,即在进展编辑与删除操作时不会联合立异用任何主键存款和储蓄的实行业内部容,那样就会生出脏数据。所以大家得以换一种思路来促成,大家能够将那个额外的主键和对应的值生成缓存组合key,里面储存对应的记录实体id,也正是说在储存记录实体时,如故利用原来的主键id存款和储蓄该实体,然后用额外主键和对应值生成缓存组合key中蕴藏主键id,在获得记录实体时,先用那些组合key提取对应的id,再用那几个id来赢得记录实体。那几个注解好像有点绕,我们温馨debug一下就很轻便领会个中的规律了,下边看代码:

    def set_model_for_cache(self, pk, value, time=43200):
        """更新存储在缓存中的数据库记录,缓存过期时间为12小时"""
        # 生成缓存key
        key = self.get_cache_key(pk)
        # 存储到nosql缓存中
        cache_helper.set(key, value, time)

  6.从session中取妥当前用户登6时所蕴藏的地点id,然后经过该id读取对应的岗位权限

 

 1     def get_model_for_cache_of_where(self, where):
 2         """
 3         通过条件获取记录实体————条件必须是额外的主键,也就是说记录是唯一的(我们经常需要使用key、编码或指定条件来获取记录,这时可以通过当前方法来获取)
 4         :param where: 查询条件
 5         :return: 记录实体
 6         """
 7         # 生成实体缓存key
 8         model_cache_key = self.__table_name + encrypt_helper.md5(where)
 9         # 通过条件从缓存中获取记录id
10         pk = cache_helper.get(model_cache_key)
11         # 如果主键id存在,则直接从缓存中读取记录
12         if pk:
13             return self.get_model_for_cache(pk)
14 
15         # 否则从数据库中获取
16         result = self.get_model(where)
17         if result:
18             # 存储条件对应的主键id值到缓存中
19             cache_helper.set(model_cache_key, result.get(self.__pk_name))
20             # 存储记录实体到缓存中
21             self.set_model_for_cache(result.get(self.__pk_name), result)
22             return result

 

  七.从菜单实体中领到菜单id,与地方权限举办比较,决断当前用户是还是不是具有访问该接口的权限,假若有则跳过,未有则不容访问。

  做到这一步,二个简约的通过主键值读取数据表记录实体的OHummerH二M方法就成功了。

  上面改变调用例子(请查看login.py第叁五行周边)

  接着是收获缓存对象方法

  具体代码如下:

  为了让那几个读取记录实体的功力能采用的愈益普及,大家还须要对它进行改建与加工。

1     ##############################################################
2     ### 获取登录用户记录,并进行登录验证 ###
3     ##############################################################
4     sql = """select * from manager where login_name='%s'""" % (username,)
5     # 从数据库中读取用户信息
6     manager_result = db_helper.read(sql)
7     # 判断用户记录是否存在
8     if not manager_result:
9         return web_helper.return_msg(-1, '账户不存在')
    def get_model_for_cache(self, pk):
        """从缓存中读取数据库记录"""
        # 生成缓存key
        key = self.get_cache_key(pk)
        # 从缓存中读取数据库记录
        result = cache_helper.get(key)
        # 缓存中不存在记录,则从数据库获取
        if not result:
            result = self.get_model_for_pk(pk)
            self.set_model_for_cache(pk, result)
        if result:
            return result
        else:
            return {}
 1 #!/usr/bin/env python 2 # coding=utf-8 3  4 from bottle import request 5 from common import web_helper 6 from logic import menu_info_logic, positions_logic 7  8 def check_user_power(): 9     """检查当前用户是否有访问当前接口的权限"""10     # 获取当前页面原始路由11     rule = request.route.rule12     # 获取当前访问接口方式(get/post/put/delete)13     method = request.method.lower()14 15     # 获取来路url16     http_referer = request.environ.get('HTTP_REFERER')17     if http_referer:18         # 提取页面url地址19         index = http_referer.find('?')20         if index == -1:21             url = http_referer[http_referer.find('/', 8) + 1:]22         else:23             url = http_referer[http_referer.find('/', 8) + 1: index]24     else:25         url = ''26 27     # 组合当前接口访问的缓存key值28     key = url + method + '(' + rule + ')'29     # 从菜单权限缓存中读取对应的菜单实体30     menu_info = menu_info_logic.MenuInfoLogic()31     model = menu_info.get_model_for_url32     if not model:33         web_helper.return_raise(web_helper.return_msg(-1, "您没有访问权限1" + key))34 35     # 读取session36     session = web_helper.get_session()37     if session:38         # 从session中获取当前用户登录时所存储的职位id39         positions = positions_logic.PositionsLogic()40         page_power = positions.get_page_power(session.get('positions_id'))41         # 从菜单实体中提取菜单id,与职位权限进行比较,判断当前用户是否拥有访问该接口的权限42         if page_power.find(',' + str(model.get('id', -1)) + ',') == -1:43             web_helper.return_raise(web_helper.return_msg(-1, "您没有访问权限2"))44     else:45         web_helper.return_raise(web_helper.return_msg(-404, "您的登录已失效,请重新登录"))

  在开头以前,大家再持续思索一下,大家获得记录实体,通过主键查询只是诸多办法中的个中一个,我们还会日常使用各个口径的结合来举办询问,读取记录实体,所以那里我们能够完结自定义规则查询的章程

  大家得以退换为:

  大家首先要做的平等是生成缓存key,然后调用get方法从缓存中读取对象,实施完后,必要决断该指标是还是不是留存缓存中,借使不存在则意味该对象并未有存款和储蓄到缓存中或它可能存款和储蓄过期了,所以须要再行从数据库中读取出来,并将它存款和储蓄到缓存中,然后将读抽取来的笔录实体再次来到出去。

  对于眼下所讲的美食指南权限缓存,上边详细讲明一下。

    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
1     ##############################################################
2     ### 获取登录用户记录,并进行登录验证 ###
3     ##############################################################
4     _manager_logic = manager_logic.ManagerLogic()
5     # 从数据库中读取用户信息
6     manager_result = _manager_logic.get_model_for_cache_of_where('login_name=' + string(username))
7     # 判断用户记录是否存在
8     if not manager_result:
9         return web_helper.return_msg(-1, '账户不存在')

 

  由于菜单跟接口都游人如织,我们在做权限推断时,就必要在访问接口时,自动相配找到该接口对应的菜单项,然后才得以依据菜单id和权限字符进行相比较,判断是还是不是持有操作权限,而自动相配那里要是间接通过数据库查找的话,操作会相比复杂,也会潜移默化使用质量,所以大家能够透过将在菜单管理中注册的菜单项进行解说,按一定的平整组合生成对应的缓存key,存款和储蓄到nosql中,当访问接口时,大家根据规则组合成对应的key直接在nosql中搜索就足以兑现大家想要的机能了。当然首先次访问或大家清除缓存后,那几个key值是不设有的,所以大家得以加个判定,要是缓存不存在时,重新加载生成对应的key就足以了。

  代码看起来与眼前的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)

  还有登入接口最底部,更新管理员最后登陆时、登陆ip和拉长登五遍数须求改动,具体代码如下:

    def get_value_for_cache(self, pk, column_name):
        """获取指定记录的字段值"""
        return self.get_model_for_cache(pk).get(column_name)
 1     def get_model_for_url(self, key): 2         """通过当前页面路由url,获取菜单对应的记录""" 3         # 使用md5生成对应的缓存key值 4         key_md5 = encrypt_helper.md5 5         # 从缓存中提取菜单记录 6         model = cache_helper.get 7         # 记录不存在时,运行记录载入缓存程序 8         if not model: 9             self._load_cache()10             model = cache_helper.get11         return model12 13     def _load_cache:14         """全表记录载入缓存"""15         # 生成缓存载入状态key,主要用于检查是否已执行了菜单表载入缓存判断16         cache_key = self.__table_name + '_is_load'17         # 将自定义的key存储到全局缓存队列中(关于全局缓存队列请查看前面ORM对应章节说明)18         self.add_relevance_cache_in_list(cache_key)19         # 获取缓存载入状态,检查记录是否已载入缓存,是的话则不再执行20         if cache_helper.get(cache_key):21             return22         # 从数据库中读取全部记录23         result = self.get_list()24         # 标记记录已载入缓存25         cache_helper.set(cache_key, True)26         # 如果菜单表没有记录,则直接退出27         if not result:28             return29         # 循环遍历所有记录,组合处理后,存储到nosql缓存中30         for model in result.get('rows', {}):31             # 提取菜单页面对应的接口(后台菜单管理中的接口值,同一个菜单操作时,经常需要访问多个接口,所以这个值有中存储多们接口值)32             interface_url = model.get('interface_url', '')33             if not interface_url:34                 continue35             # 获取前端html页面地址36             page_url = model.get('page_url', '')37 38             # 同一页面接口可能有多个,所以需要进行分割39             interface_url_arr = interface_url.replace('\n', '').replace(' ', '').split(',')40             # 逐个接口处理41             for interface in interface_url_arr:42                 # html+接口组合生成key43                 url_md5 = encrypt_helper.md5(page_url + interface)44                 # 存储到全局缓存队列中,方便菜单记录更改时,自动清除这些自定义缓存45                 self.add_relevance_cache_in_list46                 # 存储到nosql缓存47                 cache_helper.set(url_md5, model)

  改产生功后,使用前边的单元测试跑一下,能够见见再次来到结果一致。扩大了get_model()方法之后,大家就可以灵活的自定义任意的询问条件来读取记录了。那里要小心的是,使用get_model()方法查询时,有望在询问时会再次来到多条记下,那几个主意它只回去第三条记下。供给回到多条记下时,能够行使大家继承封装的别的O福睿斯M方法。

1 ##############################################################
2     ### 更新用户信息到数据库 ###
3     ##############################################################
4     # 更新当前管理员最后登录时间、Ip与登录次数(字段说明,请看数据字典)
5     sql = """update manager set last_login_time=%s, last_login_ip=%s, login_count=login_count+1 where id=%s"""
6     # 组合更新值
7     vars = ('now()', ip, manager_id,)
8     # 写入数据库
9     db_helper.write(sql, vars)

  它直接调用获取缓存对象方法,然后从再次回到的指标中读取钦定的字段值就能够了

  那里的权力管理逻辑有点绕,须要认真思索与debug检查,技巧真的明白。其余,也能够由此后台菜单管理中,故意修改菜单项的少数值,来检查那里的代码处理与转移。

 

  大家能够转移为:

 

  完结上述代码以往,权限的拍卖就马到成功了,接下去只须求在各种后台管理接口中增加上面代码就能够产生接口的访问权限调整了。

  

 1     ##############################################################
 2     ### 更新用户信息到数据库 ###
 3     ##############################################################
 4     # 更新当前管理员最后登录时间、Ip与登录次数(字段说明,请看数据字典)
 5     fields = {
 6         'last_login_time': 'now()',
 7         'last_login_ip': string(ip),
 8         'login_count': 'login_count+1',
 9     }
10     # 写入数据库
11     _manager_logic.edit_model(manager_id, fields)

  删除缓存方法也很简短,生成缓存key后,直接调用delete进行删减。对于删除方法,有时候调用不知是否nosql本身bug难点,还是在主从关系的nosql中读写分离会引起删除退步,要是现身那种景况,能够将delete改为set,将该缓存set为空就能够消除这一个标题

@get('/api/main/menu_info/')def callback():    """    主页面获取菜单列表数据    """    # 检查用户权限    _common_logic.check_user_power()

  本文对应的源码下载 (为了有利于大家精通,源码包只放了那两章所用到的一部分代码)

  对于字段值,借使为字符串、具体时刻、json等类型的,也正是说需求用单撇号括起来的,大家就必要调用string_helper模块的string方法举行转移,它可认为变量扩张单撇号,假若一直赋字符串值,生成的sql语句是尚未单撇号的,那里要留心一下

    def del_model_for_cache(self, pk):
        """删除缓存中指定数据"""
        # 生成缓存key
        key = self.get_cache_key(pk)
        # log_helper.info(key)
        # 存储到nosql缓存中
        cache_helper.delete(key)

  具体大家能够查阅小说前边提供的源码,看看后台管理接口处理就知道了。

 

  假如是数值类型,直接写值就可以了,当然平昔赋字符串值也一向不涉及,因为生成sql是不会自动抬高单撇号的

  PS:在选取缓存操作时,有时我们直接对数据库实行操作,就会挑起数据与缓存不相配,出现脏数据的意况,这时在后台扩充清空缓存的操作,直接调用cache_helper.clear()进行清空缓存。

  正文对应的源码下载

 

  要是要赋postgresql系统变量,如now(),直接像上边那样写就可以了

 

版权申明:本文原创发布于和讯,作者为AllEmpty正文欢迎转发,但未经笔者同意必须保留此段证明,且在小说页面鲜明地点给出原来的文章连接,不然正是侵权。

版权申明:本文原创公布于 博客园,作者为 AllEmpty 本文欢迎转发,但未经我同意必须保留此段证明,且在篇章页面显著地方给出原版的书文连接,不然视为侵权。

  借使字段是数值型,要让它实行总括,直接像上边那样写也行,能够是多少个字段用加号连起来。当然你也足以将字段时读出来进行测算后再赋值提交也不曾难点

  基本方法都达成了,接下去就是要对O奥德赛M的删除与修章实行改建了,让它们活动依据须要对缓存进行对应操作,让缓存与数量表中的记录保持1致。

python开拓QQ群:66905847五、7334663二1作者博客:

python开荒QQ群:669058475   
笔者博客:

  具体操作供给我们温馨多debug,多测试使用才领悟怎么选用到真正项目中。

  在改换时,我们只要求对删除与修改操作进行拍卖,对新扩展与查询操作不要求操作,因为新扩大的笔录,它并在缓存中并不存在,所以不须要张开操作,而查询也不会改造加多少内容,只有进行删除和修改操作时,才会转移数据内容,那时就需求改换缓存,让多太傅持1致。

 

 

  更动编辑记录实体方法

 

 

 1     def edit(self, fields, wheres='', returning='', is_update_cache=True):
 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 in fields.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         if wheres:
21             parameter['wheres'] = ' where ' + wheres
22         else:
23             parameter['wheres'] = ''
24 
25         # 如果有指定返回参数,则添加
26         if returning:
27             parameter['returning'] = ', ' + returning
28         else:
29             parameter['returning'] = ''
30 
31         # 生成sql语句
32         sql = "update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s" % parameter
33         sql = sql % fields
34 
35         result = self.execute(sql)
36         if result:
37             # 判断是否删除对应的缓存
38             if is_update_cache:
39                 # 循环删除更新成功的所有记录对应的缓存
40                 for model in result:
41                     self.del_model_for_cache(model.get('id', 0))
42         return result

  本文对应的源码下载

  大家能够见到,该办法扩大了is_update_cache 是还是不是同步立异缓存参数,那是因为我们在使用缓存时会存在有的破例境况,比如说批量创新异常的大多据时,如若使用循环逐条清理对应缓存时,会据有较多资源,我们得以关掉缓存的一同更新,直接调用clear清空全数缓存会尤其便捷;又例如,页面访问数的翻新,它会更新的老大频仍,大家不须求实时清除,能够选拔任何措施触发清理,也可以将点击数用独立缓存存款和储蓄使用等

 

  而清理缓存,我们只须要将缓存内容一贯删除就足以了,因为实践更新之后,再次回到的记录实体没有设置为*时,只回去主键id,直接设置的话会招致缓存数据丢失细节的难点,其它,大家实行更新之后,该记录也不自然还会被读抽出来。

版权注脚:本文原创揭橥于 博客园,作者为 AllEmpty 正文欢迎转发,但未经作者同意必须保留此段评释,且在篇章页面彰着地方给出原来的书文连接,不然正是侵权。

 

python开荒QQ群:66905847五   
小编博客:

  删除记录也举办一样的改建

 1     def delete(self, wheres='', returning='', is_update_cache=True):
 2         """
 3         批量删除数据库记录
 4         :param wheres: 删除条件
 5         :param returning: 删除成功后,返回的字段名
 6         :param is_update_cache: 是否同步更新缓存
 7         :return:
 8         """
 9         # 如果存在条件
10         if wheres:
11             wheres = ' where ' + wheres
12 
13         # 如果有指定返回参数,则添加
14         if returning:
15             returning = ', ' + returning
16 
17         # 生成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         if result:
22             # 同步删除对应的缓存
23             if is_update_cache:
24                 for model in result:
25                     self.del_model_for_cache(model.get('id', 0))
26         return result

 

  对于缓存基本上就那三个要开始展览改建的操作了。在贯彻支付中,大家认真想1想,其实大家还会设有1些非正规的动静,比如说大家对数据实行加工处理后,将加工后的值存款和储蓄到缓存中,而对相关记录进行改造或删除操作之后,由于这么些缓存它与记录并未关系,所以实行有关操作之后,它就成为孤岛,不会实时同步,产生脏数据。所以我们要求有3个效率,能够将它们管理起来,与该数据表的修改和删除操作关联起来,进行改造和删除操作后一起清除这么些越发缓存。

  依据那么些供给,大家就须求再扩大多个缓存操作方法,用来储存这个独特的缓存名称,然后在张开更换和删除操作时,同步清除那么些特殊缓存。

  首先咱们要求在伊始化方法中,增添3个绑定该数据表的大局缓存变量self.__cache_list,它由表名称+_澳门葡京备用网址,cache_list组成。

 1     def __init__(self, db, is_output_sql, table_name, column_name_list='*', pk_name='id'):
 2         """类初始化"""
 3         # 数据库参数
 4         self.__db = db
 5         # 是否输出执行的Sql语句到日志中
 6         self.__is_output_sql = is_output_sql
 7         # 表名称
 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     def add_relevance_cache_in_list(self, key):
 2         """将缓存名称存储到列表里————主要存储与记录变更关联的"""
 3         # 从nosql中读取全局缓存列表
 4         cache_list = cache_helper.get(self.__cache_list)
 5         # 判断缓存列表是否有值,有则进行添加操作
 6         if cache_list:
 7             # 判断是否已存储列表中,不存在则执行添加操作
 8             if not key in cache_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)

  推行该办法,会将大家自定义的缓存名称存储到全局缓存变量中

 

  接着大家再加多2个拔除全体特别缓存的法子

 1     def del_relevance_cache(self):
 2         """删除关联缓存————将和数据表记录关联的,个性化缓存全部删除"""
 3         # 从nosql中读取全局缓存列表
 4         cache_list = cache_helper.get(self.__cache_list)
 5         # 清除已删除缓存列表
 6         cache_helper.delete(self.__cache_list)
 7         if cache_list:
 8             # 执行删除操作
 9             for cache in cache_list:
10                 cache_helper.delete(cache)

 

  加多完结之后,我们再来改动一下修改与删除代码,只须要在里头增添祛除全体尤其缓存方法就能够了

澳门葡京备用网址 5澳门葡京备用网址 6

 1     def edit(self, fields, wheres='', returning='', is_update_cache=True):
 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 in fields.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         if wheres:
21             parameter['wheres'] = ' where ' + wheres
22         else:
23             parameter['wheres'] = ''
24 
25         # 如果有指定返回参数,则添加
26         if returning:
27             parameter['returning'] = ', ' + returning
28         else:
29             parameter['returning'] = ''
30 
31         # 生成sql语句
32         sql = "update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s" % parameter
33         sql = sql % fields
34 
35         result = self.execute(sql)
36         if result:
37             # 判断是否删除对应的缓存
38             if is_update_cache:
39                 # 循环删除更新成功的所有记录对应的缓存
40                 for model in result:
41                     self.del_model_for_cache(model.get('id', 0))
42                 # 同步删除与本表关联的缓存
43                 self.del_relevance_cache()
44         return result
45 
46     def delete(self, wheres='', returning='', is_update_cache=True):
47         """
48         批量删除数据库记录
49         :param wheres: 删除条件
50         :param returning: 删除成功后,返回的字段名
51         :param is_update_cache: 是否同步更新缓存
52         :return:
53         """
54         # 如果存在条件
55         if wheres:
56             wheres = ' where ' + wheres
57 
58         # 如果有指定返回参数,则添加
59         if returning:
60             returning = ', ' + returning
61 
62         # 生成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         if result:
67             # 同步删除对应的缓存
68             if is_update_cache:
69                 for model in result:
70                     self.del_model_for_cache(model.get('id', 0))
71                 # 同步删除与本表关联的缓存
72                 self.del_relevance_cache()
73         return result

View Code

  

  O宝马X3M的缓存退换就满门做到了,上面是完好代码

澳门葡京备用网址 7澳门葡京备用网址 8

  1 #!/usr/bin/env python
  2 # coding=utf-8
  3 
  4 from common import db_helper, cache_helper
  5 
  6 
  7 class LogicBase():
  8     """逻辑层基础类"""
  9 
 10     def __init__(self, db, is_output_sql, table_name, column_name_list='*', pk_name='id'):
 11         """类初始化"""
 12         # 数据库参数
 13         self.__db = db
 14         # 是否输出执行的Sql语句到日志中
 15         self.__is_output_sql = is_output_sql
 16         # 表名称
 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_list'
 24 
 25     #####################################################################
 26     ### 执行Sql ###
 27 
 28     def select(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 not result:
 34                 result = []
 35         return result
 36 
 37     def execute(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             if result:
 43                 db.commit()
 44             else:
 45                 result = []
 46         return result
 47 
 48     def copy(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         return result
 54 
 55     def get_model(self, wheres):
 56         """通过条件获取一条记录"""
 57         # 如果有条件,则自动添加where
 58         if wheres:
 59             wheres = ' where ' + wheres
 60 
 61         # 合成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         if result:
 67             return result[0]
 68         return {}
 69 
 70     def get_model_for_pk(self, pk, wheres=''):
 71         """通过主键值获取数据库记录实体"""
 72         if not pk:
 73             return {}
 74         # 组装查询条件
 75         wheres = '%s = %s' % (self.__pk_name, str(pk))
 76 
 77         return self.get_model(wheres)
 78 
 79     def get_value(self, column_name, wheres=''):
 80         """
 81         获取指定条件的字段值————多于条记录时,只取第一条记录
 82         :param column_name: 单个字段名,如:id
 83         :param wheres: 查询条件
 84         :return: 7 (指定的字段值)
 85         """
 86         if not column_name:
 87             return None
 88         elif wheres:
 89             wheres = ' where ' + wheres
 90 
 91         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         if result:
 96             return result[0].get(column_name)
 97 
 98     def get_value_list(self, column_name, wheres=''):
 99         """
100         获取指定条件记录的字段值列表
101         :param column_name: 单个字段名,如:id
102         :param wheres: 查询条件
103         :return: [1,3,4,6,7]
104         """
105         if not column_name:
106             column_name = self.__pk_name
107         elif wheres:
108             wheres = ' where ' + wheres
109 
110         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 and isinstance(result, list):
115             return result[0].get('list')
116         else:
117             return []
118 
119     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','name'
130         #   而value_list为:'%(id)s,%(name)s'
131         #   最终而value_list为字符串对应名称位置会被替换成相应的值
132         for key in fields.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         if returning:
144             parameter['returning'] = ', ' + returning
145         else:
146             parameter['returning'] = ''
147 
148         # 生成可以使用字典替换的字符串
149         sql = "insert into %(table_name)s (%(key_list)s) values (%(value_list)s) returning %(pk_name)s %(returning)s" % parameter
150         # 将生成好的字符串替字典参数值,生成最终可执行的sql语句
151         sql = sql % fields
152 
153         result = self.execute(sql)
154         if result:
155             return result[0]
156         return {}
157 
158     def edit(self, fields, wheres='', returning='', is_update_cache=True):
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 in fields.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         if wheres:
178             parameter['wheres'] = ' where ' + wheres
179         else:
180             parameter['wheres'] = ''
181 
182         # 如果有指定返回参数,则添加
183         if returning:
184             parameter['returning'] = ', ' + returning
185         else:
186             parameter['returning'] = ''
187 
188         # 生成sql语句
189         sql = "update %(table_name)s set %(field_list)s %(wheres)s returning %(pk_name)s %(returning)s" % parameter
190         sql = sql % fields
191 
192         result = self.execute(sql)
193         if result:
194             # 判断是否删除对应的缓存
195             if is_update_cache:
196                 # 循环删除更新成功的所有记录对应的缓存
197                 for model in result:
198                     self.del_model_for_cache(model.get('id', 0))
199                 # 同步删除与本表关联的缓存
200                 self.del_relevance_cache()
201         return result
202 
203     def edit_model(self, pk, fields, wheres='', returning=''):
204         """编辑单条数据库记录"""
205         if not pk:
206             return {}
207         elif wheres:
208             wheres = self.__pk_name + ' = ' + str(pk) + ' and ' + wheres
209         else:
210             wheres = self.__pk_name + ' = ' + str(pk)
211 
212         return self.edit(fields, wheres, returning)
213 
214     def delete(self, wheres='', returning='', is_update_cache=True):
215         """
216         批量删除数据库记录
217         :param wheres: 删除条件
218         :param returning: 删除成功后,返回的字段名
219         :param is_update_cache: 是否同步更新缓存
220         :return:
221         """
222         # 如果存在条件
223         if wheres:
224             wheres = ' where ' + wheres
225 
226         # 如果有指定返回参数,则添加
227         if returning:
228             returning = ', ' + returning
229 
230         # 生成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         if result:
235             # 同步删除对应的缓存
236             if is_update_cache:
237                 for model in result:
238                     self.del_model_for_cache(model.get('id', 0))
239                 # 同步删除与本表关联的缓存
240                 self.del_relevance_cache()
241         return result
242 
243     def delete_model(self, pk, wheres='', returning='', is_update_cache=True):
244         """删除单条数据库记录"""
245         if not pk:
246             return {}
247         elif wheres:
248             wheres = self.__pk_name + ' = ' + str(pk) + ' and ' + wheres
249         else:
250             wheres = self.__pk_name + ' = ' + str(pk)
251 
252         return self.delete(wheres, returning)
253 
254     def get_list(self, column_name_list='', wheres='', page_number=None, page_size=None, orderby=None, table_name=None):
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 not table_name:
275             table_name = self.__table_name
276         # 初始化查询字段名
277         if not column_name_list:
278             column_name_list = self.__column_name_list
279         # 初始化查询条件
280         if wheres:
281             # 如果是字符串,表示该查询条件已组装好了,直接可以使用
282             if isinstance(wheres, str):
283                 wheres = 'where ' + wheres
284             # 如果是list,则表示查询条件有多个,可以使用join将它们用and方式组合起来使用
285             elif isinstance(wheres, list):
286                 wheres = 'where ' + ' and '.join(wheres)
287         # 初始化排序
288         if not orderby:
289             orderby = self.__pk_name + ' desc'
290         # 初始化分页查询的记录区间
291         paging = ''
292 
293         with db_helper.PgHelper(self.__db, self.__is_output_sql) as db:
294             #############################################################
295             # 判断是否需要进行分页
296             if not page_size is None:
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                     return data
304 
305                 # 设置记录总数量
306                 data['records'] = result[0].get('records')
307 
308                 #########################################################
309                 ### 设置分页索引与页面大小 ###
310                 if page_size <= 0:
311                     page_size = 10
312                 # 计算总分页数量:通过总记录数除于每页显示数量来计算总分页数量
313                 if data['records'] % page_size == 0:
314                     page_total = data['records'] // page_size
315                 else:
316                     page_total = data['records'] // page_size + 1
317                 # 判断页码是否超出限制,超出限制查询时会出现异常,所以将页面索引设置为最后一页
318                 if page_number < 1 or page_number > page_total:
319                     page_number = page_total
320                 # 记录总页面数量
321                 data['total'] = page_total
322                 # 记录当前页面值
323                 data['page'] = page_number
324                 # 计算当前页面要显示的记录起始位置(limit指定的位置)
325                 record_number = (page_number - 1) * page_size
326                 # 设置查询分页条件
327                 paging = ' limit ' + str(page_size) + ' offset ' + str(record_number)
328             #############################################################
329 
330             ### 按条件查询数据库记录
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             if result:
339                 data['rows'] = result
340                 # 不需要分页查询时,直接在这里设置总记录数
341                 if page_size is None:
342                     data['records'] = len(result)
343 
344         return data
345 
346     def get_count(self, wheres=''):
347         """获取指定条件记录数量"""
348         if wheres:
349             wheres = ' where ' + wheres
350         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         # 如果查询存在记录,则返回true
354         if result:
355             return result[0].get('total')
356         return 0
357 
358     def get_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         # 如果查询存在记录,则返回true
364         if result and result[0].get('total'):
365             return result[0].get('total')
366         return 0
367 
368     def get_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         # 如果查询存在记录,则返回true
374         if result and result[0].get('min'):
375             return result[0].get('min')
376 
377     def get_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         # 如果查询存在记录,则返回true
383         if result and result[0].get('max'):
384             return result[0].get('max')
385 
386             #####################################################################
387 
388 
389     #####################################################################
390     ### 缓存操作方法 ###
391 
392     def get_cache_key(self, pk):
393         """获取缓存key值"""
394         return ''.join((self.__table_name, '_', str(pk)))
395 
396     def set_model_for_cache(self, pk, value, time=43200):
397         """更新存储在缓存中的数据库记录,缓存过期时间为12小时"""
398         # 生成缓存key
399         key = self.get_cache_key(pk)
400         # 存储到nosql缓存中
401         cache_helper.set(key, value, time)
402 
403     def get_model_for_cache(self, pk):
404         """从缓存中读取数据库记录"""
405         # 生成缓存key
406         key = self.get_cache_key(pk)
407         # 从缓存中读取数据库记录
408         result = cache_helper.get(key)
409         # 缓存中不存在记录,则从数据库获取
410         if not result:
411             result = self.get_model_for_pk(pk)
412             self.set_model_for_cache(pk, result)
413         if result:
414             return result
415         else:
416             return {}
417 
418     def get_value_for_cache(self, pk, column_name):
419         """获取指定记录的字段值"""
420         return self.get_model_for_cache(pk).get(column_name)
421 
422     def del_model_for_cache(self, pk):
423         """删除缓存中指定数据"""
424         # 生成缓存key
425         key = self.get_cache_key(pk)
426         # log_helper.info(key)
427         # 存储到nosql缓存中
428         cache_helper.delete(key)
429 
430     def add_relevance_cache_in_list(self, key):
431         """将缓存名称存储到列表里————主要存储与记录变更关联的"""
432         # 从nosql中读取全局缓存列表
433         cache_list = cache_helper.get(self.__cache_list)
434         # 判断缓存列表是否有值,有则进行添加操作
435         if cache_list:
436             # 判断是否已存储列表中,不存在则执行添加操作
437             if not key in cache_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)
444 
445     def del_relevance_cache(self):
446         """删除关联缓存————将和数据表记录关联的,个性化缓存全部删除"""
447         # 从nosql中读取全局缓存列表
448         cache_list = cache_helper.get(self.__cache_list)
449         # 清除已删除缓存列表
450         cache_helper.delete(self.__cache_list)
451         if cache_list:
452             # 执行删除操作
453             for cache in cache_list:
454                 cache_helper.delete(cache)
455 
456     #####################################################################

View Code

 

 

版权表明:本文原创发布于 博客园,作者为 AllEmpty 本文欢迎转发,但未经小编同意必须保留此段注明,且在小说页面明显地方给出原来的小说连接,不然视为侵权。

python开辟QQ群:669058475   
小编博客:

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website