日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python sqlite3事务_python使用上下文管理器实现sqlite3事务机制

發布時間:2024/9/27 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python sqlite3事务_python使用上下文管理器实现sqlite3事务机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如題,本文記錄如何使用python上下文管理器的方式管理sqlite3的句柄創建和釋放以及事務機制。

1、python上下文管理(with)

python上下文管理(context),解決的是這樣一類問題,在進入邏輯之前需要進行一些準備工作,在退出邏輯之前需要進行一些善后工作,上下文管理可以使得這種場景變得清晰和可控。

with語句是python上下文管理的基本用法,例如讀寫文件

with open('filea', r) as f:

f.readlines()

file使用的就是上下文管理機制,這樣對于打開文件句柄和釋放文件句柄無須我們額外的投入精力。

2、sqlite3

sqlite3是一個嵌入式的文件數據庫,無須開啟額外的進程和端口,就可以通過文件讀取的方式實現數據庫的操作。優點是輕量級并且支持事務和觸發器等高級特性。

sqlite3在python句柄創建和管理上跟mysql表現的很相似。

3、代碼

我們先貼上本文簡述的這段代碼,然后后面我們在做詳細解釋。

#-*- coding:utf-8 -*-

importsqlite3importtracebackclassSqliteDB(object):def __init__(self, database='sqlitedb', isolation_level='', ignore_exc=False):

self.database=database

self.isolation_level=isolation_level

self.ignore_exc=ignore_exc

self.connection=None

self.cursor=Nonedef __enter__(self):try:

self.connection= sqlite3.connect(database=self.database, isolation_level=self.isolation_level)

self.cursor=self.connection.cursor()returnself.cursorexceptException, ex:

traceback.print_exc()raiseexdef __exit__(self, exc_type, exc_val, exc_tb):try:if not exc_type isNone:

self.connection.rollback()returnself.ignore_excelse:

self.connection.commit()exceptException, ex:

traceback.print_exc()raiseexfinally:

self.cursor.close()

self.connection.close()

我們給出一個使用的case

if __name__ == '__main__':#建表

with SqliteDB('test') as db:

db.execute('create table if not exists user (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(100), age INTEGER)')#創建一條記錄, 如果拋出異常, 可以測試事務回滾

with SqliteDB('test') as db:

db.execute('insert into user (name, age) values (?, ?)', ('Tom', 10))#raise Exception()

#查詢記錄

with SqliteDB('test') as db:

query_set= db.execute('select * from user where name=? limit ?', ('Tom', 100,)).fetchall()printlen(query_set)for item inquery_set:printitem#刪除記錄

with SqliteDB('test') as db:

query_set= db.execute('delete from user where name=?', ('Tom',))

可以看到通過with語句打開了數據庫的句柄,執行數據庫操作后,我們并沒有管理句柄的釋放和事務回滾。

代碼的輸出是:

1(6, u'Tom', 10)

當打開raise Exception()的注釋,表示在插入的過程中遇到了異常。這時候所有connection中未被提交的數據將被回滾。

那么,這些如何做到的呢?

上下文管理是通過類SqliteDB中的__enter__和__exit__兩個魔法函數實現的。

1、enter函數,用來實現處理進入with_body之前的準備工作,這里是創建connect和cursor,enter方法返回了cursor。

enter函數如果有返回值,那么可以賦值給as后面的變量,如果沒有返回,可以簡單的去掉as子句即可。我們給出一個沒有as子句的例子

lock =threading.Lock()

with lock:pass

如果enter函數拋出異常,那么在執行with語句的時候會拋出這個異常,并且中斷程序。

2、邏輯上,enter函數之后,便開始執行with_body內的代碼,with_body里的代碼包含sql語句和一些業務邏輯,這里說明一下,只要是拋出異常就會觸發事務的回滾機制,而不會區分到底是sql語句執行異常還是業務邏輯出現的異常。

3、exit函數,在with_body執行成功或者拋出異常后會執行exit函數。

exit函數傳入三個變量,分別是exc_type異常類型,exc_val異常值,exc_tb錯誤堆棧信息。如果程序正常,那么三個值都是None,相反如果不是None,那么可以就此判斷with_body產生了異常。

這里,我們判斷了exc_type是否為None,來區分是否拋出了異常,如果拋出了異常我們使用connection.rollback進行了事務的回滾,否則我們使用connection.commit進行事務提交。

要注意的是,在出現異常的時候,返回了一個ignore_exc,這個返回如果是True,表示忽略這個異常,這個異常將不會向上級調用拋出,如果返回的是None或者False,異常將會向上拋出。實際中我們還是希望異常能夠跑出來,方便處理,所以這里我們默認為False。

注意:

isolation_level這個字段是隔離級別,這里我們不做深入的說明。需要知道的是這個字段

1)傳入空字符串‘’,表示手動提交commit,這時需要程序中顯示的執行connection.commit進行事務提交,sql中的dml語句才會生效。

2)傳入None,表示開啟自動提交,這時候自動提交commit,無需在程序中connection.commit進行事務提交。

總結

以上是生活随笔為你收集整理的python sqlite3事务_python使用上下文管理器实现sqlite3事务机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。