MySQL 數據庫
數據庫指的是以一定方式存儲在一起、能為多個用戶共享、具有盡可能曉得冗余度、與應用程序彼此獨立的數據集合。
到目前位置,地球上有三種類型的數據:
- 關系型數據庫:MySQL、Microsoft Access、SQL Server、Oracle……
- 非關系型數據庫:MongoDB、BigTable(Google)、……
- 鍵值數據庫:Apache Cassandra(Facebook)、LevelDB(Google)……
在此,只是簡單介紹 python 如何去連接 mysql 數據庫並做一些簡單的操作
python 標准數據庫接口為 Python DB-API,Python DB-API為開發人員提供了數據庫應用編程借口。
python 數據庫接口支持非常多的數據庫。你可以訪問python 數據庫接口及 API查看詳細的支持數據庫列表。
python 的 DB-API,為大多數的數據庫實現了接口,使用它連接各數據庫后,就可以用相同的方式操作各數據庫。
Python DB-API 使用流程:
- 引入 API 模塊
- 獲取與數據庫的連接
- 執行 SQL 語句和存儲過程
- 關閉數據庫連接
Mysql 游標
游標定義:在操作 MySQL 的時候我們知道 MySQL 檢索操作返回一組稱為結果集的行。這組返回的行都是與 SQL 語句相匹配的行(零行或多行)。使用簡單的 select 語句,例如,沒有般大得到第一行、下一行或者前十行,也不存在每次一行的處理所有行的簡單辦法(相對於成批的處理它們)。有時,需要在檢索出來的行中間前進或者后退一行或多行。這就是使用游標的原因。游標(cursor)是一個存儲在 MySQL 服務器上的數據庫查詢,它不是一條 select 語句,而是被該語句檢索出來的結果集。在存儲了游標之后,應用程序可以根據滾動或者瀏覽器中的數據。游標主要用於交互式應用,其中用戶需要滾動屏幕上的數據,並對數據進行瀏覽或作出更改。
注意:不想多數 DBMS,MySQL游標只能用於存儲過程(和函數)
個人理解:游標相當於將 select 的結果存起來,當你需要多少就去那兒取;不像 select 語句把結果全部展示給你。
數據庫連接池
官方:數據庫連接池(Connection pooling)是程序啟動是建立足夠的數據庫連接,並將這些連接組成一個連接池,由程序動態的對池中的連接進行申請、使用、釋放。
個人理解:創建數據庫連接是一個很耗時的操作,也容易對數據庫造成安全隱患。所以,在程序初始化的時候,集中創建多個數據庫連接,並把他們集中管理,供程序使用,可以保證較快的數據庫讀寫速度,還更加安全可靠。
數據庫連接池的運行機制
- 數據初始化時創建連接池
- 使用時向連接池申請可用連接
- 使用完畢,將連接返還給連接池
- 程序退出時,斷開所有連接,並釋放資源
如下圖示:
在 python 中也有模塊來創建 MySQL 連接池
模塊名為 DButils
,可以通過pip install DButils
安裝
import MySQLdb
from DBUtils.PooledDB import PooledDB
db_config = {
'host' : '192.168.189.100',
'user' : 'root',
'passwd' : '',
'db' : 'test',
'port' : 33066
}
# conn = MySQLdb.connect(**db_config)
conn_pool = PooledDB(MySQLdb, maxcached=5, **db_config)
# print dir(conn_pool.connection())
conn = conn_pool.connection()
cur = conn.cursor()
SQL = 'select * from student'
cur.execute(SQL)
result = cur.fetchall()
print result
#結果為
#((1L, 'zhangsan'), (2L, 'wangwu'), (3L, 'wangwu'), (4L, 'wagwu'))
安裝 python-MySQLdb
python-MySQLdb 是一個接口程序,python 通過它對 mysql 數據實現各種操作。
如果要源碼安裝,可以這里下載: python-MySQLdb
連接 MySQL 數據庫
import MySQLdb
db_config = {
'host' : '192.168.189.100', #填寫主機名(string)
'user' : 'root', #填寫登錄用戶(string)
'passwd' : 'XXXXXX', #填寫登錄密碼(string)
'db' : 'test', #選擇數據庫(string)
'port' : 33066 #填寫端口(int)
'charset':'utf-8' #設定字符集
}
try:
conn = MySQLdb.connect(**db_config)
except Exception as e:
raise e
finally:
print " mysql 連接成功!"
其實,關於 connect 的參數還有很多,可以閱讀源碼。不過,上面幾個是常用的,其他的看情況使用。
python 操作數據庫
python 建立了與數據的連接,其實是建立了一個MySQLdb.connect()
的實例對象,或者泛泛的稱為連接對象,python
就是通過連接對象和數據庫對話。這個對象常用的方法有:
commit()
:如果數據庫表進行了修改,提交保存當前的數據。如果此用戶沒有權限就什么也不會發生。rollback()
:回滾操作cursor([cursorclass])
:返回連接的游標對象。通過游標執行 SQL 查詢並檢查結果。游標比連接支持更多的方法,而且可能在程序中更好用。close()
:關閉連接。此后,連接對象和游標都不再可用了
Python
和數據之間的連接建立起來之后,要操作數據庫,就需要讓python
對數據庫執行 SQL 語句。python
是通過游標執行 SQL 語句的。所以,連接建立之后,就要利用連接對象得到游標對象,方法如下:
cur = conn.cursor()
print type(cur) # 結果為: <class 'MySQLdb.cursors.Cursor'>
此后,就可以利用游標對象的方法對數據庫進行操作。游標對象的常用方法:
名稱 | 描述 |
---|---|
close() | 關閉游標,之后游標不可用 |
execute(query[,args]) | 執行一條 SQL 語句,可以帶參數 |
executemany(query,pseq) | 對序列 pseq 中的每個參數執行 SQL 語句 |
fetchone() | 返回一條查詢結果 |
fetchmany([size]) | 返回 size 條結果 |
nextset() | 移動到下一個結果 |
scroll(value,mode='relative') | 移動游標到指定行,如果mode='relative',則表示從 當前所在行移動 value 條,如果mode='absolute',則 表示從結果集的第一行移動 value 條 |
插入數據
例如,要在數據表 student 中插入一條記錄,使得:id = 2,name = 'wangwu',,可以這樣做
cur.execute("insert into student(id,name) values (%s,%s);",(2,'wangwu'))
conn.commit()
cur.close()
conn.close()
插入多條語句
例如,要在數據表 student 中插入多條記錄,使得:id = 5,name = 'zhao';id = 6,name = 'qian',可以這樣做
add_list = [(5,'zhao'),(6,'qian')]
cur.executemany('insert into student(id,name) values (%s,%s)',add_list)
conn.commit()
cur.close()
conn.close()
讀取操作
任何數據庫上的讀操作表示要從數據庫中讀取一些有用的信息。
在建立數據庫連接后,就可以對此數據庫進行查詢了。可以使用 fetchone()
方法獲取單條記錄或fetchall()
方法從數據庫表中獲取多個值。
fetchone()
- 獲取查詢結果集的下一行。結果集是當使用游標對象來查詢表時返回的對象fetchall()
- 獲取結果集中的所有行。如果已經從結果集中提取了一些行,則從結果集中檢出剩余的行。rowcount
- 這是一個只讀屬性,並返回受execute()
方法影響的行數。
cur.execute("select * from student;")
result = cur.fetchall()
print result
# 返回元素是元組
((1L, 'zhangsan'), (2L, 'wangwu'), (3L, 'wangwu'), (4L, 'wagwu'))
移動游標
通過游標找出來的對象,在讀取的時候有一個特點,就是那個游標會移動。在第一次操作了 print cur.fetchall()
后,因為是將所有的對象都打印出來,游標就從第一條移動到最后一條。當print
結束后,游標已經在最后一條的后面了。接下來如果再次打印,游標已經指到最后,將會返回空。
fetchone()
- 游標會一列一列向下移動
fetchall()
- 游標會從最開始一下移動到最后
不過我們可以使用 scroll()
來手動移動游標。
cur.scroll(n)
或者cur.scroll(n,'relative')
:意思是相對當前位置向上或者向下移動,n
為正數,表示向下,n
為負數,表示向上
cur.scroll(n,'absolute')
:與相對當前位置移動相反,n
指定序列對象,序列對象的順序是從0開始的。
cur.scroll(2,'absolute') #回到序號是2,但指向第三條
cur.scroll(0,'absolute') #回到序號是0,即指向tuple的第一條
轉換元組元素類型
默認情況下,游標返回的對象的類型為元組組成的元組,
而且可以看到游標類為 MySQLdb.cursors.Cursor
。我們可以轉換元組內的元素類型,將元組轉換為字典,方便讀取"key-value"
# 創建游標對象,添加一條記錄
cur = conn.cursor()
print type(cur)
# 查看一條記錄
cur.execute("select * from student;")
result = cur.fetchone()
print result
# 結果為:
<class 'MySQLdb.cursors.Cursor'>
(1L, 'zhangsan')
將游標默認引用的類修改為MySQLdb.cursors.DictCursor
,生成字典組成的列表:
# 創建游標對象,添加一條記錄
cur = conn.cursor(MySQLdb.cursors.DictCursor)
print type(cur)
# 查看一條記錄
cur.execute("select * from student;")
result = cur.fetchone()
print result
# 結果為:
<class 'MySQLdb.cursors.DictCursor'>
{'id': 1L, 'name': 'zhangsan'}
可以更加方便取值。
值得注意的一點是:當你操作數據完畢,“不要忘記關門”:
cur.close() #關閉游標,相當與對象緩存的地方
conn.close() #關閉數據庫連接