我的第一个python web开发框架(11)——工具函数包说明(二)

  db_helper.py是数据库操作包,主要有两个函数,分别是read()数据库读操作函数和write()数据库写操作函数。这个包的代码是从小戴同学分享的博文改造过来的。

 1 #!/usr/bin/env python
 2 # coding=utf-8
 3 
 4 import psycopg2
 5 from common import log_helper
 6 from config import const
 7 
 8 # 初始化数据库参数
 9 db_name = const.DB_NAME
10 db_host = const.DB_HOST
11 db_port = const.DB_PORT
12 db_user = const.DB_USER
13 db_pass = const.DB_PASS
14 
15 
16 def read(sql):
17     """
18     连接pg数据库并进行数据查询
19     如果连接失败,会把错误写入日志中,并返回false,如果sql执行失败,也会把错误写入日志中,并返回false
20     如果所有执行正常,则返回查询到的数据,这个数据是经过转换的,转成字典格式,方便模板调用,其中字典的key是数据表里的字段名
21     """
22     try:
23         # 连接数据库
24         conn = psycopg2.connect(database=db_name, user=db_user, password=db_pass, host=db_host, port=db_port)
25         # 获取游标
26         cursor = conn.cursor()
27     except Exception as e:
28         print(e.args)
29         log_helper.error('连接数据库失败:' + str(e.args))
30         return False
31     try:
32         # 执行查询操作
33         cursor.execute(sql)
34         # 将返回的结果转换成字典格式
35         data = [dict((cursor.description[i][0], value) for i, value in enumerate(row)) for row in cursor.fetchall()]
36     except Exception as e:
37         print(e.args)
38         log_helper.error('sql执行失败:' + str(e.args) + ' sql:' + str(sql))
39         return False
40     finally:
41         # 关闭游标和数据库链接
42         cursor.close()
43         conn.close()
44     # 返回结果(字典格式)
45     return data
46 
47 
48 def write(sql, vars):
49     """
50     连接pg数据库并进行写的操作
51     如果连接失败,会把错误写入日志中,并返回false,如果sql执行失败,也会把错误写入日志中,并返回false,如果所有执行正常,则返回true
52     """
53     try:
54         # 连接数据库
55         conn = psycopg2.connect(database=db_name, user=db_user, password=db_pass, host=db_host, port=db_port)
56         # 获取游标
57         cursor = conn.cursor()
58     except Exception as e:
59         print(e.args)
60         log_helper.error('连接数据库失败:' + str(e.args))
61         return False
62     try:
63         # 执行sql语句
64         cursor.execute(sql, vars)
65         # 提交事务
66         conn.commit()
67     except Exception as e:
68         print(e.args)
69         # 如果出错,则事务回滚
70         conn.rollback()
71         log_helper.error('sql执行失败:' + str(e.args) + ' sql:' + str(sql))
72         return False
73     else:
74         # 获取数据
75         try:
76             data = [dict((cursor.description[i][0], value) for i, value in enumerate(row))
77                          for row in cursor.fetchall()]
78         except Exception as e:
79             # 没有设置returning或执行修改或删除语句时,记录不存在
80             data = None
81     finally:
82         # 关闭游标和数据库链接
83         cursor.close()
84         conn.close()
85 
86     # 如果写入数据后,将数据库返回的数据返回给调用者
87     return data
View Code

  read(sql)是用来执行数据库查询操作,里面没有事务提交,所以用它来执行增删改操作时,虽然能提交成功,但执行后数据库记录也不会有什么变化,所以只能用它来执行select语句

  write(sql, data)是用来执行数据库写操作的,write函数执行后会返回下面几种状态:

  1.False状态(数据库链接失败、sql语句不正确、链接数据库操时等执行数据库出现异常时返回这个状态)

  2.None状态(sql语句没有添加RETURNING id代码指定sql语句执行结束后返回指定字段值时出现;你如果修改代码第80行,data = None为data = True,执行成功时则会返回True状态)

  3.[] (sql语句添加了returning函数,且执行修改或删除时,记录不存在)

  4.{'id': 1,}(sql语句添加了returning函数,执行成功后返回我们指定的字段值)

  PS:我们在执行新增的时候,如果想要获取新增的id,postgresql有一个非常好用的函数returning,只需要在增删改语句的后面添加returning idreturning id,namereturning *等你想要返回的字段名称,语句执行成功以后都会返回这些指定的字段值,大家可以尝试修改测试用例代码,看看返回的值是什么。

#!/usr/bin/evn python
# coding=utf-8import unittest
from common import db_helperclass DbHelperTest(unittest.TestCase):"""数据库操作包测试类"""def setUp(self):"""初始化测试环境"""print('------ini------')def tearDown(self):"""清理测试环境"""print('------clear------')def test(self):# 新增记录,不带return参数sql = """INSERT INTO product_class(name, is_enable)VALUES (%s, %s)"""data = ('糖果', 1)result = db_helper.write(sql, data)print(result)# 新增记录,使用return参数返回新增idsql = """INSERT INTO product_class(name, is_enable)VALUES (%s, %s)RETURNING id;"""data = ('饼干', 1)result = db_helper.write(sql, data)print(result)# 修改不存在的记录sql = """UPDATE product_classSET name=%s, is_enable=%sWHERE id=10000RETURNING id;"""data = ('糖果', 1)result = db_helper.write(sql, data)print(result)# 查询记录sql = """SELECT * FROM product_class"""result = db_helper.read(sql)print(result)if __name__ == '__main__':unittest.main()

  执行结果

------ini------
None
[{'id': 2}]
[]
[{'id': 1, 'name': '糖果', 'add_time': datetime.datetime(2017, 10, 16, 14, 51, 49), 'is_enable': 1}, {'id': 2, 'name': '饼干', 'add_time': datetime.datetime(2017, 10, 16, 15, 30, 50), 'is_enable': 1}]
------clear------

  

 

  encrypt_helper.py是加密操作包,目前只有md5加密函数,其他加密函数以后有需要再添加进来

#!/usr/bin/evn python
# coding=utf-8import hashlibdef md5(text):"""md5加密函数"""md5 = hashlib.md5()if not isinstance(text, bytes):text = str(text).encode('utf-8')md5.update(text)return md5.hexdigest()

  md5()参数类型支持各种类型,如果参数为非bytes类型时会自动转换为str类型来进行操作,例如以下测试用例,大家也可以尝试用元组、字典或列表类型测试看看结果

#!/usr/bin/evn python
# coding=utf-8import unittest
from common import encrypt_helperclass DbHelperTest(unittest.TestCase):"""数据库操作包测试类"""def setUp(self):"""初始化测试环境"""print('------ini------')def tearDown(self):"""清理测试环境"""print('------clear------')def test(self):result = encrypt_helper.md5(1)print(result)self.assertEqual(result, 'c4ca4238a0b923820dcc509a6f75849b')result = encrypt_helper.md5('1')print(result)self.assertEqual(result, 'c4ca4238a0b923820dcc509a6f75849b')result = encrypt_helper.md5(b'1')print(result)self.assertEqual(result, 'c4ca4238a0b923820dcc509a6f75849b')if __name__ == '__main__':unittest.main()

  执行结果

------ini------
c4ca4238a0b923820dcc509a6f75849b
c4ca4238a0b923820dcc509a6f75849b
c4ca4238a0b923820dcc509a6f75849b
------clear------

 

 

  except_helper.py包主要功能是获取代码当前位置的堆栈信息,它被log_helper.py包的error()错误日志记录函数调用,输出发生错误时的堆栈信息内容,方便开发人员分析代码异常。

#!/usr/bin/evn python
# coding=utf-8import os
import sysdef detailtrace():"""获取程序当前运行的堆栈信息"""retStr = ""f = sys._getframe()f = f.f_back        # first frame is detailtrace, ignore itwhile hasattr(f, "f_code"):co = f.f_coderetStr = "%s(%s:%s)->"%(os.path.basename(co.co_filename),co.co_name,f.f_lineno) + retStrf = f.f_backreturn retStr

 

 

  json_helper.py包里只有一个日期格式化类。

#!/usr/bin/evn python
# coding=utf-8import json
import datetimeclass CJsonEncoder(json.JSONEncoder):def default(self, obj):if isinstance(obj, datetime.datetime):return obj.strftime('%Y-%m-%d %H:%M:%S')elif isinstance(obj, datetime.date):return obj.strftime('%Y-%m-%d')else:return json.JSONEncoder.default(self, obj)

   python的json将时间类型转换为字符串时,它会处理不了出现异常,需要使用这个自定义类进行格式化处理

  比如我们如果直接这样对时间类型进行转换时,就会出现异常:

    def test(self):js = {'test5': datetime.datetime.now(),}print(js)result = json.dumps(js)print(result)

  执行结果:

------ini------
{'test5': datetime.datetime(2017, 10, 16, 16, 56, 58, 654832)}
------clear------Error
Traceback (most recent call last):File "E:\Python\simple\code\test\json_helper_test.py", line 26, in testresult = json.dumps(js)File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\__init__.py", line 230, in dumpsreturn _default_encoder.encode(obj)File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 198, in encodechunks = self.iterencode(o, _one_shot=True)File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 256, in iterencodereturn _iterencode(o, 0)File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 179, in defaultraise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2017, 10, 16, 16, 56, 58, 654832) is not JSON serializable

  改成下面代码的话就正常了

    def test(self):js = {'test5': datetime.datetime.now(),}print(js)result = json.dumps(js, cls=json_helper.CJsonEncoder)print(result)

  执行结果

------ini------
{'test5': datetime.datetime(2017, 10, 16, 16, 59, 40, 756103)}
{"test5": "2017-10-16 16:59:40"}
------clear------

 

 

  本文对应的源码下载

 

版权声明:本文原创发表于 博客园,作者为 AllEmpty 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

python开发QQ群:669058475(本群已满)、733466321(可以加2群)    作者博客:http://www.cnblogs.com/EmptyFS/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux crontab 命令

#method 1 crontab -e crontab -u root -e #不同用户自己的任务计划 crontab -l#method 2 vim /etc/crontab# Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .--…

【Swift学习】Swift编程之旅---ARC(二十)

Swift使用自动引用计数(ARC)来跟踪并管理应用使用的内存。大部分情况下,这意味着在Swift语言中,内存管理"仍然工作",不需要自己去考虑内存管理的事情。当实例不再被使用时,ARC会自动释放这些类的实例所占用的内存。然而…

转:传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确 .

近期在做淘宝客的项目,大家都知道,淘宝的商品详细描述字符长度很大,所以就导致了今天出现了一个问题 VS的报错是这样子的 ” 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确“ 还说某个desricption 过长之类的话 直觉告诉我&#…

合并bin文件-----带boot发布版本比较好用的bat(便捷版)

直接上图上代码(代码在结尾),有不会用的可以留言: 第一步:工程介绍,关键点--- 1.bat文件放所在app和boot工程的同级目录下 2.release为运行bat自动生成文件夹 第二步:合版.bat 针对具体项目需…

关于cmake从GitHub上下载的源码启动时报错的问题

关于cmake从GitHub上下载的源码启动时报错的问题: 由于cmake会产生all_build和zero_check两个project,此时需要右击鼠标将需要运行的项目设为启动项,在进行编译,现只针对“找不到all_build文件“的出错信息,若有相关编…

Elementary OS安装Chrome

elementary os 官方网站:https://elementary.io/ 这os是真好看!首先这是基于ubuntu的,所以可以安装ubuntu的软件! 电脑必备浏览器必须是chrome呀!下载地址: https://www.chrome64bit.com/index.php/google…

spark、oozie、yarn、hdfs、zookeeper、

为什么80%的码农都做不了架构师?>>> spark、 oozie:任务调度 yarn:资源调度 hdfs:分布式文件系统 zookeeper、 转载于:https://my.oschina.net/u/3709135/blog/1556661

JLOI2016 方

bzoj4558 真是一道非常excited的题目啊…JLOI有毒 题目大意:给一个(N1)*(M1)的网格图,格点坐标为(0~N,0~M),现在挖去了K个点,求剩下多少个正方形(需要注意的是正方形可以是斜着的,多斜都可以) N…

opencv 直方图反向投影

转载至:http://www.cnblogs.com/zsb517/archive/2012/06/20/2556508.html 直方图反向投影式通过给定的直方图信息,在图像找到相应的像素分布区域,opencv提供两种算法,一个是基于像素的,一个是基于块的。 使用方法不写了…

request请求在Struts2中的处理步骤

2019独角兽企业重金招聘Python工程师标准>>> 一个请求在Struts2框架中的处理大概分为以下几个步骤 1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2 这个请求经过一系列的过滤器(Filter)(这些过滤…

vs联合torch,ZED相机api,opencv建立C++项目

ZED相机api下载及cmake教程 generate产生工程文件后打开,配置如下: 将ZED项目作为启动项 然后在main.cpp中写入自己的工程代码即可,运行也在release X64下进行 注:cmake之前源文件下main.cpp,也就是tutorial 1 - h…

使用DataGridView数据窗口控件,构建用户快速输入体验

使用DataGridView数据窗口控件,构建用户快速输入体验 在“随风飘散” 博客里面,介绍了一个不错的DataGridView数据窗口控件《DataGridView数据窗口控件开发方法及其源码提供下载》,这种控件在有些场合下,还是非常直观的。因为&…

pip安装

下载pip安装包,解压。复制到C:\Users\administrator\下,用cmd打开当前文件夹,用Python安装, Python setup.py install 安装完之后记得把Python根目录下的scripts也放在环境变量里。 以上是我pip安装的成功例子,可能不…

手把手教你用1行代码实现人脸识别 -- Python Face_recognition

2019独角兽企业重金招聘Python工程师标准>>> 环境要求: Ubuntu17.10Python 2.7.14环境搭建: 1. 安装 Ubuntu17.10 > 安装步骤在这里 2. 安装 Python2.7.14 (Ubuntu17.10 默认Python版本为2.7.14) 3. 安装 git 、cmake 、 python-pip # 安装…

pip安装的库导入pycharm中

用pip安装了一些库,但pycharm中却没有,解决方法是

一个关于解决序列化问题的编程技巧

在前一篇文章中我曾经说过,现在正在做一个小小的框架以实现采用统一的API实现对上下文(Context)信息的统一管理。这个框架同时支持Web和GUI应用,并支持跨线程传递和跨域传递(这里指在WCF服务调用中实现客户端到服务端隐…

踩坑之路anaconda创建虚拟环境

浑浑噩噩的过了三年渣硕生涯,虽然说自己是搞图像的,但基本是一些机器视觉的东西,最近突然想好好搞搞深度学习这方面,想着那就先搭搭环境跑个demo吧,经历了好多莫名其妙的踩坑操作,demo跑的终于没bug了&…

dns服务器未响应

昨天还好好的,今天打开电脑显示DNS服务器为响应。 解决办法:右击电脑下方图标栏——打开Windows任务管理器——服务——服务(s)——找到DNS client和DHCP client——右击重启

ubuntu安装pytorch镜像修改及下载

ubuntu安装pytorch镜像修改及下载 下载pytorch下载太慢,搞了很长时间,终于改好镜像能快速下载了,记录以下。 1.在/home/用户名/ 下找到/.condarc 文件,可能需要你右击鼠标显示隐藏文件才能显示, 2.把内容修改为清华等镜…

R--线性回归诊断(一)

线性回归诊断--R 【转载时请注明来源】:http://www.cnblogs.com/runner-ljt/ Ljt 勿忘初心 无畏未来 作为一个初学者,水平有限,欢迎交流指正。 在R中线性回归,一般使用lm函数就可以得到线性回归模型,但是得到的模型…