所以,我們還要建立乙個簡單可靠的資料庫訪問模型,在乙個執行緒中,能既安全又簡單地運算元據庫。
為什麼不選擇sqlalchemy?sqlalchemy太龐大,過度地物件導向設計導致api太複雜。
所以我們決定自己設計乙個封裝基本的select、insert、update和delete操作的db模組:transwarp.db
。
設計底層模組的原則是,根據上層呼叫者設計簡單易用的api介面,然後,實現模組內部**。
假設transwarp.db
模組已經編寫完畢,我們希望以這樣的方式來呼叫它:
首先,初始化資料庫連線資訊,通過create_engine()
函式:
from transwarp importdbdb.create_engine(user='
root
', password='
password
', database='
test
', host='
127.0.0.1
', port=3306)
然後,就可以直接操作sql了。
如果需要做乙個查詢,可以直接呼叫select()
方法,返回的是list,每乙個元素是用dict表示的對應的行:
users = db.select('select * from user')
#users =>#[
#,#,
##]
如果要執行insert、update或delete操作,執行update()
方法,返回受影響的行數:
n = db.update('insert into user(id, name) values(?, ?)
', 4, '
jack
')
update()
函式簽名為:
update(sql, *args)
統一用?
作為佔位符,並傳入可變引數來繫結,從根本上避免sql注入攻擊。
每個select()
或update()
呼叫,都隱含地自動開啟並關閉了資料庫連線,這樣,上層呼叫者就完全不必關心資料庫底層連線。
但是,如果要在乙個資料庫連線裡執行多個sql語句怎麼辦?我們用乙個with語句實現:
with db.connection():db.select(
'...')
db.update(
'...')
db.update(
'...
')
如果要在乙個資料庫事務中執行多個sql語句怎麼辦?我們還是用乙個with語句實現:
with db.transaction():db.select(
'...')
db.update(
'...')
db.update(
'...
')
由於模組是全域性物件,模組變數是全域性唯一變數,所以,有兩個重要的模組變數:
#db.py
#資料庫引擎物件:
class
_engine(object):
def__init__
(self, connect):
self._connect =connect
defconnect(self):
return
self._connect()
engine =none
#持有資料庫連線的上下文物件:
class
_dbctx(threading.local):
def__init__
(self):
self.connection =none
self.transactions =0
defis_init(self):
return
not self.connection is
none
definit(self):
self.connection =_lasyconnection()
self.transactions =0
defcleanup(self):
self.connection.cleanup()
self.connection =none
defcursor(self):
return
self.connection.cursor()
_db_ctx = _dbctx()
由於_db_ctx
是threadlocal
物件,所以,它持有的資料庫連線對於每個執行緒看到的都是不一樣的。任何乙個執行緒都無法訪問到其他執行緒持有的資料庫連線。
有了這兩個全域性變數,我們繼續實現資料庫連線的上下文,目的是自動獲取和釋放連線:
class_connectionctx(object):
def__enter__
(self):
global
_db_ctx
self.should_cleanup =false
ifnot
_db_ctx.is_init():
_db_ctx.init()
self.should_cleanup =true
return
self
def__exit__
(self, exctype, excvalue, traceback):
global
_db_ctx
ifself.should_cleanup:
_db_ctx.cleanup()
defconnection():
return _connectionctx()
python 模組詳解 python day 22
第三方模組 擴充套件模組 沒在安裝python直譯器的時候安裝的那些功能 自定義模組 你寫的功能如果是乙個通用的功能,那你就把它當做乙個模組 內建模組 安裝python直譯器的時候跟著裝上的那些方法 import my module 要匯入乙個py檔案的名字,但是不加.py字尾名 import my...
Python Day 2 物件導向程式設計
property裝飾器 將乙個函式變成屬性呼叫 在繫結屬性的時候,如果把屬性資料暴露出去,雖寫起來簡單但無法檢查引數,導致資料可以隨意更改。所以需要乙個set和乙個get,通過set來檢查設定引數。訪問器 getter 把乙個訪問器變為屬性只需要加上 property 只定義getter方法不定義s...
某菜菜子的Python Day2 學習小結
在進行了第一天的運算子學習後,菜菜子同學開始學習了針對python中關於資料的一些知識 python的資料結構,python的資料型別以及對應資料型別的增刪查改 數字型int 整型 float 浮點型 complex 虛數 boolean數字型別 表達真或假 x true y fal 0 false...