標籤:char 結構 style 語句 mysq 操作 false ble 伺服器端
一、DBUtils模組介紹
The DBUtils suite is realized as a Python package containing two subsets of modules, one for use with arbitrary DB-API 2 modules, the other one for use with the classic PyGreSQL module.
The dependencies of the modules in the universal DB-API 2 variant are as indicated in the following diagram:
The dependencies of the modules in the classic PyGreSQL variant are similar:
使用PyGreSQL模組實現了對PostgreSQL資料庫的操作
DBUtils是一套Python資料庫連接池包,並允許對非安全執行緒的資料庫介面進行安全執行緒封裝。DBUtils來自Webware for Python。
DBUtils提供兩種外部介面: PersistentDB :提供線程專用的資料庫連接,並自動管理串連。 PooledDB :提供線程間可共用資料庫串連,並自動管理串連。
實測證明 PersistentDB 的速度是最高的,但是在某些特殊情況下,資料庫的串連過程可能異常緩慢,而此時的PooledDB則可以提供相對來說平均連線時間比較短的管理方式。
另外,實際使用的資料庫驅動也有所依賴,比如SQLite資料庫只能使用PersistentDB作串連池。
功能
SteadyDB.py:用於穩定資料庫連接
PooledDB.py:串連池
PersistentDB.py:維持持續的資料庫連接(持久性串連)
SimplePooledDB.py:簡單串連池
SimplePooledDB :
DBUtils.SimplePooledDB 是一個非常簡單的資料庫連接池實現。他比完善的 PooledDB 模組缺少很多功能。 DBUtils.SimplePooledDB 本質上類似於 MiscUtils.DBPool 這個Webware的組成部分。你可以把它看作一種示範程式。
SteadyDB:
DBUtils.SteadyDB 是一個模組實現了”強硬”的資料庫連接,基於DB-API 2建立的原始串連。一個”強硬”的串連意味著在串連關閉之後,或者使用次數操作限制時會重新串連。
一個典型的例子是資料庫重啟時,而你的程式仍然在運行並需要訪問資料庫,或者當你的程式串連了一個防火牆後面的遠端資料庫,而防火牆重啟時丟失了狀態時。
一般來說你不需要直接使用 SteadyDB 它只是給接下來的兩個模組提供基本服務, PersistentDB 和 PooledDB 。
PersistentDB:
DBUtils.PersistentDB 實現了強硬的、安全執行緒的、頑固的資料庫連接,使用DB-API 2模組。
當一個線程首次開啟一個資料庫連接時,一個串連會開啟並僅供這個線程使用。當線程關閉串連時,串連仍然持續開啟供這個線程下次請求時使用這個已經開啟的串連。串連線上程死亡時自動關閉。
簡單的來說 PersistentDB 嘗試重用資料庫連接來提高線程化程式的資料庫訪問效能,並且他確保串連不會被線程之間共用。
因此, PersistentDB 可以在底層DB-API模組並非安全執行緒的時候同樣工作的很好,並且他會在其他線程改變資料庫會話或者使用多語句事務時同樣避免問題的發生。
PooledDB
DBUtils.PooledDB 實現了一個強硬的、安全執行緒的、有緩衝的、可複用的資料庫連接,使用任何DB-API 2模組。
PooledDB 可以在不同線程之間共用開啟的資料庫連接。這在你串連並指定 maxshared 參數,並且底層的DB-API 2介面是安全執行緒才可以,但是你仍然可以使用專用資料庫連接而不線上程之間共用串連。除了共用串連以外,還可以設立一個至少 mincached 的串連池,並且最多允許使用 maxcached 個串連,這可以同時用於專用和共用串連池。當一個線程關閉了一個非共用串連,則會返還到空閑串連池中等待下次使用。
如果底層DB-API模組是非安全執行緒的,線程鎖會確保使用 PooledDB 是安全執行緒的。所以你並不需要為此擔心,但是你在使用專用連線來改變資料庫會話或執行多命令事務時必須小心。
該選擇哪一個?
PersistentDB 和 PooledDB 都是為了重用資料庫連接來提高效能,並保持資料庫的穩定性。
所以選擇何種模組,可以參考上面的解釋。 PersistentDB 將會保持一定數量的串連供頻繁使用。在這種情況下你總是保持固定數量的串連。如果你的程式頻繁的啟動和關閉線程,最好使用 PooledDB 。後面將會提到更好的調整,尤其在使用安全執行緒的DB-API 2模組時。
當然,這兩個模組的介面是很相似的,你可以方便的在他們之間轉換,並查看哪個更好一些。
官方指南:https://cito.github.io/w4py-olde-docs/Webware/DBUtils/Docs/UsersGuide.html
使用
串連池對象只初始化一次,一般可以作為模組層級代碼來確保。 PersistentDB的串連例子:
import DBUtils.PersistentDB
persist=DBUtils.PersistentDB.PersistentDB(dbpai=MySQLdb,maxusage=1000,**kwargs)
這裡的參數dbpai指使用的底層資料庫模組,相容DB-API的。maxusage則為一個串連最大使用次數,參考了官方例子。後面的**kwargs則為實際傳遞給MySQLdb的參數。
擷取串連: conn=persist.connection() 實際編程中用過的串連直接關閉 conn.close() 即可將串連交還給串連池。
PooledDB使用方法同PersistentDB,只是參數有所不同。
-
- dbapi :資料庫介面
- mincached :啟動時開啟的空串連數量
- maxcached :串連池最大可用串連數量
- maxshared :串連池最大可共用串連數量
- maxconnections :最大允許串連數量
- blocking :達到最大數量時是否阻塞
- maxusage :單個串連最大複用次數
- setsession :用於傳遞到資料庫的準備會話,如 [”set name UTF-8″] 。
PersistentDB:為每個線程建立一個串連,線程即使調用了close方法,也不會關閉,只是把串連重新放到串連池,供自己線程再次使用。當線程終止時,串連自動關閉
PooledDB:建立一批串連到串連池,供所有線程共用使用。
from DBUtils.PersistentDB import PersistentDBimport pymysqlPOOL = PersistentDB( creator=pymysql, # 使用連結資料庫的模組 maxusage=None, # 一個連結最多被重複使用的次數,None表示無限制 setsession=[], # 開始會話前執行的命令列表。 ping=0, # ping MySQL服務端,檢查是否服務可用。 closeable=False, # 如果為False時, conn.close() 實際上被忽略,供下次使用,再線程關閉時,才會自動關閉連結。如果為True時, conn.close()則關閉連結,那麼再次調用pool.connection時就會報錯,因為已經真的關閉了串連(pool.steady_connection()可以擷取一個新的連結) threadlocal=None, # 本線程獨享值得對象,用於儲存連結化物件,如果連結化物件被重設 host=‘127.0.0.1‘, port=3306, user=‘root‘, password=‘123456‘, database=‘test‘, charset=‘utf8‘)def func(): conn = POOL.connection(shareable=False) cursor = conn.cursor() cursor.execute(‘select * from user‘) result = cursor.fetchall() print(result) cursor.close() conn.close()if __name__ == ‘__main__‘: func()
PersistentDB
import pymysqlfrom DBUtils.PooledDB import PooledDBPOOL = PooledDB( creator=pymysql, # 使用連結資料庫的模組 maxconnections=6, # 串連池允許的最大串連數,0和None表示不限制串連數 mincached=2, # 初始化時,連結池中至少建立的閒置連結,0表示不建立 maxcached=5, # 連結池中最多閑置的連結,0和None不限制 maxshared=3, # 連結池中最多共用的連結數量,0和None表示全部共用。PS: 無用,因為pymysql和MySQLdb等模組的 threadsafety都為1,所有值無論設定為多少,_maxcached永遠為0,所以永遠是所有連結都共用。 blocking=True, # 串連池中如果沒有可用串連後,是否阻塞等待。True,等待;False,不等待然後報錯 maxusage=None, # 一個連結最多被重複使用的次數,None表示無限制 setsession=[], # 開始會話前執行的命令列表。 ping=0, # ping MySQL服務端,檢查是否服務可用。 host=‘127.0.0.1‘, port=3306, user=‘root‘, password=‘123456‘, database=‘test‘, charset=‘utf8‘)def func(): # 檢測當前正在運行串連數的是否小於最大連結數,如果不小於則:等待或報raise TooManyConnections異常 # 否則 # 則優先去初始化時建立的連結中擷取連結 SteadyDBConnection。 # 然後將SteadyDBConnection對象封裝到PooledDedicatedDBConnection中並返回。 # 如果最開始建立的連結沒有連結,則去建立一個SteadyDBConnection對象,再封裝到PooledDedicatedDBConnection中並返回。 # 一旦關閉連結後,串連就返回到串連池讓後續線程繼續使用。 conn = POOL.connection() # print(th, ‘連結被拿走了‘, conn1._con) # print(th, ‘池子裡目前有‘, pool._idle_cache, ‘\r\n‘) cursor = conn.cursor() cursor.execute(‘select * from user‘) result = cursor.fetchall() print(result) conn.close()if __name__ == ‘__main__‘: func()
PooledDB
cmd下載安裝DBUtils模組: easy_install -U DBUtils
二、orm
ORM全稱“Object Relational Mapping”,即對象-關係映射,就是把關聯式資料庫的一行映射為一個對象,也就是一個類對應一個表,這樣,寫代碼更簡單,不用直接操作SQL語句。當我們需要對資料庫進行操作時,勢必需要通過串連資料、調用sql語句、執行sql語句等操作,ORM將資料庫中的表,欄位,行與我們物件導向編程的類及其方法,屬性等一一對應,即將該部分操作封裝起來,程式猿不需懂得sql語句即可完成對資料庫的操作。
要編寫一個ORM架構,所有的類都只能動態定義,因為只有使用者才能根據表的結構定義出對應的類來,使用 metaclass 。
1、 在執行個體化一個user對象的時候,可以user=User(name=‘lqz‘,password=‘123‘)
2 、也可以 user=User()
user[‘name‘]=‘lqz‘
user[‘password‘]=‘123‘
3 、也可以 user=User()
user.name=‘lqz‘
user.password=‘password‘
前兩種,可以通過繼承字典dict來實現,第三種,用getattr和setattr
__getattr__ 攔截點號運算。當對未定義的屬性名稱和執行個體進行點號運算時,就會用屬性名稱作為字串調用這個方法。如果繼承樹可以找到該屬性,則不調用此方法
__setattr__會攔截所有屬性的的指派陳述式。如果定義了這個方法,self.arrt = value 就會變成self,__setattr__("attr", value).這個需要注意。當在__setattr__方法內對屬性進行賦值是,不可使用self.attr = value,因為他會再次調用self,__setattr__("attr", value),則會形成無窮遞迴迴圈,最後導致堆疊溢位異常。應該通過對屬性字典做索引運算來賦值任何執行個體屬性,也就是使用self.__dict__[‘name‘] = value
具體實現參考:80340978
三、cookie、session、tokensession
session的中文翻譯是“會話”,當使用者開啟某個web應用時,便與web伺服器產生一次session。伺服器使用session把使用者的資訊臨時儲存在了伺服器上,使用者離開網站後session會被銷毀。這種使用者資訊儲存方式相對cookie來說更安全,可是session有一個缺陷:如果web伺服器做了負載平衡,那麼下一個操作請求到了另一台伺服器的時候session會丟失。
cookie
cookie是儲存在本地終端的資料。cookie由伺服器產生,發送給瀏覽器,瀏覽器把cookie以kv形式儲存到某個目錄下的文字檔內,下一次請求同一網站時會把該cookie發送給伺服器。由於cookie是存在用戶端上的,所以瀏覽器加入了一些限制確保cookie不會被惡意使用,同時不會佔據太多磁碟空間,所以每個域的cookie數量是有限的。
cookie的組成有:名稱(key)、值(value)、有效域(domain)、路徑(域的路徑,一般設定為全域:"\")、失效時間、安全標誌(指定後,cookie只有在使用SSL串連時才發送到伺服器(https))。下面是一個簡單的js使用cookie的例子:
使用者登入時產生cookie:
document.cookie = "id="+result.data[‘id‘]+"; path=/";
document.cookie = "name="+result.data[‘name‘]+"; path=/";
document.cookie = "avatar="+result.data[‘avatar‘]+"; path=/";
使用到cookie時做如下解析:
var cookie = document.cookie;var cookieArr = cookie.split(";");var user_info = {};for(var i = 0; i < cookieArr.length; i++) {
user_info[cookieArr[i].split("=")[0]] = cookieArr[i].split("=")[1];
}
$(‘#user_name‘).text(user_info[‘ name‘]);
$(‘#user_avatar‘).attr("src", user_info[‘ avatar‘]);
$(‘#user_id‘).val(user_info[‘ id‘]);
token
token的意思是“令牌”,是使用者身份的驗證方式,最簡單的token組成:uid(使用者唯一的身份標識)、time(目前時間的時間戳記)、sign(簽名,由token的前幾位+鹽以雜湊演算法壓縮成一定長的十六進位字串,可以防止惡意第三方拼接token請求伺服器)。還可以把不變的參數也放進token,避免多次查庫
cookie 和session的區別
1、cookie資料存放在客戶的瀏覽器上,session資料放在伺服器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session。
3、session會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能
考慮到減輕伺服器效能方面,應當使用COOKIE。
4、單個cookie儲存的資料不能超過4K,很多瀏覽器都限制一個網站最多儲存20個cookie。
5、所以個人建議:
將登陸資訊等重要訊息存放為SESSION
其他資訊如果需要保留,可以放在COOKIE中
token 和session 的區別
session 和 oauth token並不矛盾,作為身份認證 token安全性比session好,因為每個請求都有簽名還能防止監聽以及重放攻擊,而session就必須靠鏈路層來保障通訊安全了。如上所說,如果你需要實現有狀態的會話,仍然可以增加session來在伺服器端儲存一些狀態
App通常用restful api跟server打交道。Rest是stateless的,也就是app不需要像browser那樣用cookie來儲存session,因此用session token來標示自己就夠了,session/state由api server的邏輯處理。 如果你的後端不是stateless的rest api, 那麼你可能需要在app裡儲存session.可以在app裡嵌入webkit,用一個隱藏的browser來管理cookie session.
Session 是一種HTTP儲存機制,目的是為無狀態的HTTP提供的持久機制。所謂Session 認證只是簡單的把User 資訊儲存到Session 裡,因為SID 的不可預測性,暫且認為是安全的。這是一種認證手段。 而Token ,如果指的是OAuth Token 或類似的機制的話,提供的是 認證 和 授權 ,認證是針對使用者,授權是針對App 。其目的是讓 某App有權利訪問 某使用者 的資訊。這裡的 Token是唯一的。不可以轉移到其它 App上,也不可以轉到其它 使用者 上。 轉過來說Session 。Session只提供一種簡單的認證,即有此 SID,即認為有此 User的全部權利。是需要嚴格保密的,這個資料應該只儲存在站方,不應該共用給其它網站或者第三方App。 所以簡單來說,如果你的使用者資料可能需要和第三方共用,或者允許第三方調用 API 介面,用 Token 。如果永遠只是自己的網站,自己的 App,用什麼就無所謂了。
token就是令牌,比如你授權(登入)一個程式時,他就是個依據,判斷你是否已經授權該軟體;cookie就是寫在用戶端的一個txt檔案,裡麵包括你登入資訊之類的,這樣你下次在登入某個網站,就會自動調用cookie自動登入使用者名稱;session和cookie差不多,只是session是寫在伺服器端的檔案,也需要在用戶端寫入cookie檔案,但是檔案裡是你的瀏覽器編號.Session的狀態是儲存在伺服器端,用戶端只有session id;而Token的狀態是儲存在用戶端。
4月16日 python學習總結 DBUtils模組、orm 和 cookie、session、token