我的第一个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,一经查实,立即删除!

相关文章

ASP.NET:在一般处理程序中通过 Session 保存验证码却无法显示图片?

1 using System.Drawing;2 using System.Web;3 using System.Web.SessionState;4 5 /// <summary>6 /// CaptchaHandler 的摘要说明7 /// </summary>8 public class CaptchaHandler : IHttpHandler, IRequiresSessionState  //简记&#xff1a;我需要Session9 { …

[LINK]用Python计算昨天、今天和明天的日期时间

用Python计算昨天、今天和明天的日期时间 转载于:https://www.cnblogs.com/Athrun/p/5477651.html

Windows系统下oracle数据库每天定时备份

第一步&#xff1a;建立备份脚本oraclebackup.bat 首先建立一个备份bat文件&#xff0c;在D盘下新建备份目录oraclebackup&#xff0c;将oracle安装目录下的EXP.EXE复制到此目录下&#xff0c;再新建一个文本文件oraclebackup.txt&#xff0c;内容如下&#xff1a; echo off ec…

面试题3:二维数组查找

1 bool Find(const int *matrix, int rows, int columns, int number)2 {3 int key;4 int indexRow;5 int indexCol;6 7 /*合法性检查*/8 if((NULL matrix)||(rows < 0)||(columns <0))9 { 10 return false; 11 } 12 13 /*提升…

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) # | | | .--…

[译] RNN 循环神经网络系列 2:文本分类

原文地址&#xff1a;RECURRENT NEURAL NETWORKS (RNN) – PART 2: TEXT CLASSIFICATION原文作者&#xff1a;GokuMohandas译文出自&#xff1a;掘金翻译计划本文永久链接&#xff1a;github.com/xitu/gold-m…译者&#xff1a;Changkun Ou校对者&#xff1a;yanqiangmiffy, To…

[置顶] Android开发者官方网站文档 - 国内踏得网镜像

Mark 一下&#xff1a; 镜像地址&#xff1a;http://wear.techbrood.com/index.html Android DevelopTools: http://www.androiddevtools.cn/ 转载于:https://www.cnblogs.com/superle/p/4561856.html

Java实现选择排序

选择排序思想就是选出最小或最大的数与第一个数交换&#xff0c;然后在剩下的数列中重复完成该动作。 package Sort;import java.util.Arrays;public class SelectionSort {public static int selectMinKey(int[] list, int beginIdx) {int idx beginIdx;int temp list[begin…

ASP.NET MVC中ViewData、ViewBag和TempData

1.ViewData 1.1 ViewData继承了IDictionary<string, object>,因此在设置ViewData属性时,传入key必须要字符串型别,value可以是任意类型。 1.2 ViewData它只会存在这次的HTTP要求而已,而不像Session可以将数据带到下HTTP要求。 public class TestController : Controller{…

java 正则表达式验证邮箱格式是否合规 以及 正则表达式元字符

package com.ykmimi.testtest; /*** 测试邮箱地址是否合规* author ukyor**/ public class EmailTest {public static void main(String[] args) {//定义要匹配的Email地址的正则表达式//其中\w代表可用作标识符的字符,不包括$. \w表示多个// \\.\\w表示点.后面有\w 括号{2,3}…

镜头选型

景深&#xff1a; 光圈越大&#xff0c;光圈值越小&#xff0c;景深越小 光圈越小&#xff0c;光圈值越大&#xff0c;景深越深 焦距越长&#xff0c;视角越小&#xff0c;主体像越大&#xff0c;景深越小 主体越近&#xff0c;景深越小

迅雷账号

账号 jiangchnangli:1 密码 892812 网址 http://www.s8song.net/read-htm-tid-4906661.html漫晴xydcq7681转载于:https://www.cnblogs.com/wlzhang/p/4563118.html

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

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

像元大小及精度

说完了光学系统的分辨率之后我们来看看相机的图像分辨率。图像分辨率比较好理解&#xff0c;就是单位距离内的像用多少个像素来显示。以我们的ORCA-Flash4.0为例&#xff0c;芯片的像元大小为 6.5 μm&#xff0c;在 40X物镜的放大倍率下&#xff0c;1 μm的物经光学系统放大为…

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

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

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

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

第五天 断点续传和下载

1 断点续传&#xff0c; 2.多线程下载原理 3.httpUtils 多线程断点下载的使用。 ------------- 1.拿到需要下载的文件的大小&#xff0c;和需要初始的线程数 2.得到每个线程需要下载的大小&#xff0c;最后一个线程负责将剩下的数据全部下载。 3.同时需要设置一个与下载文件同大…

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

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

一个人的Scrum之准备工作

在2012年里&#xff0c;我想自己一人去实践一下Scrum&#xff0c;所以才有了这么一个开篇。 最近看了《轻松的Scrum之旅》这本书&#xff0c;感觉对我非常有益。书中像讲述故事一样描述了在执行Scrum过程中的点点滴滴&#xff0c; 仿佛我也跟着进行了一次成功的Scrum。同样的&a…

Elementary OS安装Chrome

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