我的第一個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.pswp.cn/news/257212.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257212.shtml
英文地址,請注明出處:http://en.pswp.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…