我的第一個python web開發架構(11)——工具函數包說明(二),pythonweb

來源:互聯網
上載者:User

我的第一個python web開發架構(11)——工具函數包說明(二),pythonweb

  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_NAME10 db_host = const.DB_HOST11 db_port = const.DB_PORT12 db_user = const.DB_USER13 db_pass = const.DB_PASS14 15 16 def read(sql):17 """18 串連pg資料庫並進行資料查詢19 如果串連失敗,會把錯誤寫入日誌中,並返回false,如果sql執行失敗,也會把錯誤寫入日誌中,並返回false20 如果所有執行正常,則返回查詢到的資料,這個資料是經過轉換的,轉成字典格式,方便模板調用,其中字典的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 False31 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 False40 finally:41 # 關閉遊標和資料庫連結42 cursor.close()43 conn.close()44 # 返回結果(字典格式)45 return data46 47 48 def write(sql, vars):49 """50 串連pg資料庫並進行寫的操作51 如果串連失敗,會把錯誤寫入日誌中,並返回false,如果sql執行失敗,也會把錯誤寫入日誌中,並返回false,如果所有執行正常,則返回true52 """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 False62 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 False73 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 = None81 finally:82 # 關閉遊標和資料庫連結83 cursor.close()84 conn.close()85 86 # 如果寫入資料後,將資料庫返回的資料返回給調用者87 return dataView 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 id或returning id,name或returning *等你想要返回的欄位名稱,語句執行成功以後都會返回這些指定的欄位值,大家可以嘗試修改測試案例代碼,看看返回的值是什麼。

#!/usr/bin/evn python# coding=utf-8import unittestfrom 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參數返回新增id        sql = """            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_class               SET name=%s, is_enable=%s            WHERE id=10000            RETURNING 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 unittestfrom 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------c4ca4238a0b923820dcc509a6f75849bc4ca4238a0b923820dcc509a6f75849bc4ca4238a0b923820dcc509a6f75849b------clear------

 

 

  except_helper.py包主要功能是擷取代碼當前位置的堆棧資訊,它被log_helper.py包的error()錯誤記錄檔記錄函數調用,輸出發生錯誤時的堆棧資訊內容,方便開發人員分析代碼異常。

#!/usr/bin/evn python# coding=utf-8import osimport sysdef detailtrace():    """擷取程式當前啟動並執行堆棧資訊"""    retStr = ""    f = sys._getframe()    f = f.f_back        # first frame is detailtrace, ignore it    while hasattr(f, "f_code"):        co = f.f_code        retStr = "%s(%s:%s)->"%(os.path.basename(co.co_filename),                  co.co_name,                  f.f_lineno) + retStr        f = f.f_back    return retStr

 

 

  json_helper.py包裡只有一個日期格式化類。

#!/usr/bin/evn python# coding=utf-8import jsonimport 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------ErrorTraceback (most recent call last):  File "E:\Python\simple\code\test\json_helper_test.py", line 26, in test    result = json.dumps(js)  File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\__init__.py", line 230, in dumps    return _default_encoder.encode(obj)  File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 198, in encode    chunks = self.iterencode(o, _one_shot=True)  File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 256, in iterencode    return _iterencode(o, 0)  File "C:\Users\Empty\AppData\Local\Programs\Python\Python35-32\lib\json\encoder.py", line 179, in default    raise 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
出處:http://www.cnblogs.com/EmptyFS/
有興趣的朋友可以加加python開發QQ群:669058475 ,大家一起探討。大家有問題的話可以在群裡發問,當然我平時工作也非常繁忙不一定會及時回複。

本文為AllEmpty原創,歡迎轉載,但未經同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.