27. Python對Mysql的操作(2)
1.遊標
遊標是系統為用戶開設的一個數據緩沖區,存放SQL語句的執行結果
用戶可以用SQL語句逐一從遊標中獲取記錄,並賦給主變量,交由python進一步處理,一組主變量一次只能存放一條記錄
僅使用主變量並不能完全滿足SQL語句向應用程序輸出數據的要求
遊標提供了一種對從表中檢索出的數據進行操作的靈活手段,就本質而言,遊標實際上是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制。遊標總是與一條SQL 選擇語句相關聯因為遊標由結果集(可以是零條、一條或由相關的選擇語句檢索出的多條記錄)和結果集中指向特定記錄的遊標位置組成。當決定對結果集進行處理時,必須聲明一個指向該結果集的遊標。
常用方法:
cursor(): 創建遊標對象
close(): 關閉此遊標對象
fetchone(): 得到結果集的下一行
fetchmany([size = cursor.arraysize]): 得到結果集的下幾行
fetchall(): 得到結果集中剩下的所有行
excute(sql[, args]):執行一個數據庫查詢或命令
executemany (sql, args):執行多個數據庫查詢或命令
舉例:
import MySQLdb def connect_mysql(): db_config = { ‘host‘: ‘192.168.48.128‘, ‘port‘: 3306, ‘user‘: ‘xiang‘, ‘passwd‘: ‘123456‘, ‘db‘: ‘python‘, ‘charset‘: ‘utf8‘ } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == ‘__main__‘: cnx = connect_mysql() cus = cnx.cursor() sql = ‘‘‘select * from employees;‘‘‘ try: cus.execute(sql) result1 = cus.fetchone() print(‘result1:‘) print(result1) result2 = cus.fetchmany(1) print(‘result2:‘) print(result2) result3 = cus.fetchall() print(‘result3:‘) print(result3) cus.close() cnx.commit() except Exception as e: cnx.rollback() print(‘error‘) raise e finally: cnx.close()
結果:
result1:
(1001L, u‘li‘, u‘M‘, datetime.date(2015, 4, 1))
result2:
((1002L, u‘xian‘, u‘M‘, datetime.date(2015, 4, 1)),)
result3:
((1003L, u‘sheng‘, u‘M‘, datetime.date(2015, 4, 1)),)
解釋:
1,先通過 MySQLdb.connect(**db_config) 建立mysql連接對象
2,在通過 cus = cnx.cursor() 創建遊標
3,fetchone():在最終搜索的數據中去一條數據
4,fetchmany(1) 在接下來的數據中在去1行的數據,這個數字可以自定義,定義多少就是在結果集中取多少條數據。
5,fetchall()是在所有的結果中搞出來所有的數據。
執行多條語句的sql時要註意,請閱讀一下代碼:
from demon2 import connect_mysql import MySQLdb def connect_mysql(): db_config = { "host": "192.168.48.128", "port": 3306, "user": "xiang", "passwd": "123456", "db": "python", "charset": "utf8" } try: cnx = MySQLdb.connect(**db_config) except Exception as e: raise e return cnx if __name__ == "__main__": sql = "select * from tmp;" sql1 = "insert into tmp(id) value (%s);" param = [] for i in xrange(100, 130): param.append([str(i)]) print(param) cnx = connect_mysql() cus = cnx.cursor() print(dir(cus)) try: cus.execute(sql) cus.executemany(sql1, param) # help(cus.executemany) result1 = cus.fetchone() print("result1") print(result1) result2 = cus.fetchmany(3) print("result2") print(result2) result3 = cus.fetchall() print("result3") print(result3) cus.close() cnx.commit() except Exception as e: cnx.rollback() raise e finally: cnx.close()
2.數據庫連接池
python編程中可以使用MySQLdb進行數據庫的連接及諸如 查詢/插入/更新 等操作,但是每次連接mysql數據庫請求時,都是獨立的去請求訪問,相當浪費資源,而且訪問數量達到一定數量時,對mysql的性能會產生較大的影響。因此,實際使用中,通常會使用數據庫的連接池技術,來訪問數據庫達到資源復用的目的。
python的數據庫連接池包 DBUtils:
DBUtils是一套Python數據庫連接池包,並允許對非線程安全的數據庫接口進行線程安全包裝。
DBUtils來自Webware for Python。
DBUtils提供兩種外部接口:
* PersistentDB :提供線程專用的數據庫連接,並自動管理連接。
* PooledDB :提供線程間可共享的數據庫連接,並自動管理連接。
下載地址:
https://pypi.python.org/pypi/DBUtils/
下載解壓後,使用命令進行安裝
# python setup.py install
或者使用
# pip install DBUtils
舉例:
import MySQLdb from DBUtils.PooledDB import PooledDB db_config = { "host": "192.168.48.128", "port": 3306, "user": "xiang", "passwd": "123456", "db": "python", "charset": "utf8" } pool = PooledDB(MySQLdb, 5, **db_config) # 5默認為連接池裏的最少連接數 conn = pool.connection() # 以後每次需要數據庫連接就是用 connection() 函數獲取連接就好了 cur = conn.cursor() SQL = "select * from tmp;" r = cur.execute(SQL) r = cur.fetchall() print(r) cur.close() conn.close()
PooledDB的參數:
1. mincached,最少的空閑連接數,如果空閑連接數小於這個數,pool會創建一個新的連接
2. maxcached,最大的空閑連接數,如果空閑連接數大於這個數,pool會關閉空閑連接
3. maxconnections,最大的連接數,
4. blocking,當連接數達到最大的連接數時,在請求連接的時候,如果這個值是True,請求連接的程序會一直等待,直到當前連接數小於最大連接數,如果這個值是False,會報錯,
5. maxshared 當連接數達到這個數,新請求的連接會分享已經分配出去的連接
總結:
在uwsgi中,每個http請求都會分發給一個進程,連接池中配置的連接數都是一個進程為單位的(即上面的最大連接數,都是在一個進程中的連接數),而如果業務中,一個http請求中需要的sql連接數不是很多的話(其實大多數都只需要創建一個連接),配置的連接數配置都不需要太大。
連接池對性能的提升表現在:
1.在程序創建連接的時候,可以從一個空閑的連接中獲取,不需要重新初始化連接,提升獲取連接的速度
2.關閉連接的時候,把連接放回連接池,而不是真正的關閉,所以可以減少頻繁地打開和關閉連接
3.設計表結構
在操作數據庫之前,先要設計數據庫表結構,通過分析經典的學生、課程、成績、老師幾者之間的關系,先來分析各個主體之間都有什麽屬性,並確定表結構;
在實際開發過程中,根據業務需要和業務屬性,設計不同的表結構;
以下是學生、課程、成績、老師幾者關系設計的表結構:
本文出自 “筆記空間” 博客,請務必保留此出處http://286577399.blog.51cto.com/10467610/1983939
27. Python對Mysql的操作(2)