1. 程式人生 > >Python操作數據庫之 MySQL

Python操作數據庫之 MySQL

python mysql

Python操作數據庫之MySQL

一、安裝Python-MySQLdb模塊

Python-MySQLdb是一個操作數據庫的模塊,Python 通過它對 mysql 數據實現各種操作。

如果要源碼安裝,可以這裏下載: https://pypi.Python.org/pypi/MySQL-Python/

解壓安裝包,進入解壓目錄執行以下命令安裝

python setup.py install

ubuntu 下可以這麽做:

sudo apt-get install build-essential Python-dev libmysqlclient-dev
sudo apt-get install Python-MySQLdb

pip安裝:

pip install mysql-Python

安裝之後,在 python 交互模式下:

>>> import MySQLdb

如果不報錯,恭喜你,已經安裝好了。

二、操作數據庫

操作數據庫流程:

1、導入MySQLdb模塊

2、創建數據庫連接

3、執行SQL語句和存儲過程

4、關閉數據庫連接

創建MySQL連接對象

>>> import MySQLdb
>>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123456",db="python",port=3306,charset="utf8")
>>>

命令含義解釋:

host:等號的後面應該填寫 mysql 數據庫的地址,因為就數據庫就在本機上(也稱作本地),所以使用 localhost,註意引號。如果在其它的服務器上,這裏應該填寫 ip 地址。一般中小型的網站,數據庫和程序都是在同一臺服務器(計算機)上,就使用 localhost 了。

user:登錄數據庫的用戶名,這裏一般填寫"root",還是要註意引號。當然,如果讀者命名了別的用戶名,數據庫管理者提供了專有用戶名,就更改為相應用戶。但是,不同用戶的權限可能不同,所以,在程序中,如果要操作數據庫,還要註意所擁有的權限。在這裏用 root,就放心了,什麽權限都有啦。不過,這樣做,在大型系統中是應該避免的。

passwd:上述 user 賬戶對應的登錄 mysql 的密碼。我在上面的例子中用的密碼是"123123"。不要忘記引號。

db:就是剛剛通 create 命令建立的數據庫,我建立的數據庫名字是"qiwsirtest",還是要註意引號。看官如果建立的數據庫名字不是這個,就寫自己所建數據庫名字。

port:一般情況,mysql 的默認端口是 3306,當 mysql 被安裝到服務器之後,為了能夠允許網絡訪問,服務器(計算機)要提供一個訪問端口給它。

charset:這個設置,在很多教程中都不寫,結果在真正進行數據存儲的時候,發現有亂碼。這裏我將 qiwsirtest 這個數據庫的編碼設置為 utf-8 格式,這樣就允許存入漢字而無亂碼了。註意,在 mysql 設置中,utf-8 寫成 utf8,沒有中間的橫線。但是在 Python 文件開頭和其它地方設置編碼格式的時候,要寫成 utf-8。切記!

Python 建立了與數據的連接,其實是建立了一個 MySQLdb.connect() 的實例對象,或者泛泛地稱之為連接對象,Python 就是通過連接對象和數據庫對話。這個對象常用的方法有:

commit():如果數據庫表進行了修改,提交保存當前的數據。當然,如果此用戶沒有權限就作罷了,什麽也不會發生。

rollback():如果有權限,就取消當前的操作,否則報錯。

cursor([cursorclass]):返回連接的遊標對象。通過遊標執行 SQL 查詢並檢查結果。遊標比連接支持更多的方法,而且可能在程序中更好用。

close():關閉連接。此後,連接對象和遊標都不再可用了。

創建遊標

Python 和數據之間的連接建立起來之後,要操作數據庫,就需要讓 Python 對數據庫執行 SQL 語句。Python 是通過遊標執行 SQL 語句的。所以,連接建立之後,就要利用連接對象得到遊標對象,方法如下:

>>> cur = conn.cursor()

此後,就可以利用遊標對象的方法對數據庫進行操作。那麽還得了解遊標對象的常用方法:

名稱

描述

close()

關閉遊標。之後遊標不可用

execute(query[,args])

執行一條 SQL 語句,可以帶參數

executemany(query, pseq)

對序列 pseq 中的每個參數執行 sql 語句

fetchone()

返回一條查詢結果

fetchall()

返回所有查詢結果

fetchmany([size])

返回 size 條結果

nextset()

移動到下一個結果

scroll(value,mode='relative')

移動遊標到指定行,如果 mode='relative',則表示從當前所在行移動 value ,如果 mode='absolute',則表示從結果集的第一行移動 value

插入數據

>>> cur.execute("insert into user (name,age,mail) values (%s,%s,%s)",("lulu",18,"[email protected]"))
1L
>>>

沒有報錯,並且返回一個"1L"結果,說明有一n 行記錄操作成功。

登錄MySQL,驗證數據有沒有添加成功

mysql> select * from user;
Empty set (0.00 sec)
 
mysql>

奇怪,並沒有看到插入的那條數據!到底哪裏錯了

特別註意,通過"cur.execute()"對數據庫進行操作之後,沒有報錯,完全正確,但是不等於數據就已經提交到數據庫中了,還必須要用到"MySQLdb.connect"連接對象的一個方法:commit(),將數據提交上去,也就是進行了"cur.execute()"操作,要將數據提交,必須執行:

>>> conn.commit()

再次登錄MySQL,看數據有沒有添加成功

mysql> select * from user;
+----+------+------+----------------+
| id | name | age  | mail           |
+----+------+------+----------------+
|  1 | lulu |   18 | [email protected] |
+----+------+------+----------------+
1 row in set (0.00 sec)
 
mysql>

果然如此。這就如同編寫一個文本一樣,將文字寫到文本上,並不等於文字已經保留在文本文件中了,必須執行"CTRL-S"才能保存。也就是在通過 Python 操作數據庫的時候,以"execute()"執行各種 sql 語句之後,要讓已經執行的效果保存,必須運行連接對象的"commit()"方法。

插入多條數據

>>> cur.executemany("insert into user (name,age,mail) values (%s,%s,%s)",(("google",25,"[email protected]"),("facebook",18,"[email protected]"),("github",20,"[email protected]"),("docker",10,"[email protected]")))
4L
>>>

mysql> select * from user;
+----+----------+------+----------------+
| id | name     | age  | mail           |
+----+----------+------+----------------+
|  1 | lulu     |   18 | [email protected] |
|  2 | google   |   25 | [email protected]    |
|  3 | facebook |   18 | [email protected]    |
|  4 | github   |   20 | [email protected]    |
|  5 | docker   |   10 | [email protected]    |
+----+----------+------+----------------+
5 rows in set (0.00 sec)
 
mysql>

成功插入了多條記錄。在"executemany(query, pseq)"中,query 還是一條 sql 語句,但是 pseq 這時候是一個 tuple,這個 tuple 裏面的元素也是 tuple,每個 tuple 分別對應 sql 語句中的字段列表。這句話其實被執行多次。只不過執行過程不顯示給我們看罷了。

查詢

如果要從數據庫中查詢數據,也用遊標方法來操作了。

>>> cur.execute("select * from user")
5L
>>> print cur.fetchall()
((1L, u'lulu', 18L, u'[email protected]'), (2L, u'google', 25L, u'[email protected]'), (3L, u'facebook', 18L, u'[email protected]'), (4L, u'github', 20L, u'[email protected]'), (5L, u'docker', 10L, u'[email protected]'))
>>>

cur.execute() 從數據庫查詢出來的東西,被“保存在了 cur 所能找到的某個地方”,要找出這些被保存的東西,需要用cur.fetchall()(或者 fechone 等),並且找出來之後,做為對象存在。從上面的實驗探討發現,被保存的對象是一個 tuple 中,裏面的每個元素,都是一個一個的 tuple。因此,用 for 循環就可以一個一個拿出來了。

再次執行一次上面的操作

>>> print cur.fetchall()
()
>>>

為什麽結果是空的?

原來是通過遊標找出來的對象,在讀取的時候有一個特點,就是那個遊標會移動。在第一次操作了 print cur.fetchall() 後,因為是將所有的都打印出來,遊標就從第一條移動到最後一條。當 print 結束之後,遊標已經在最後一條的後面了。接下來如果再次打印,就空了,最後一條後面沒有東西了。

再看一個實驗

>>> cur.execute("select * from user")
5L
>>> print cur.fetchone()
(1L, u'lulu', 18L, u'[email protected]')
>>> print cur.fetchone()
(2L, u'google', 25L, u'[email protected]')
>>> print cur.fetchone()
(3L, u'facebook', 18L, u'[email protected]')
>>> print cur.fetchone()
(4L, u'github', 20L, u'[email protected]')
>>> print cur.fetchone()
(5L, u'docker', 10L, u'[email protected]')
>>>

這次不一次全部打印出來了,而是一次打印一條,可以從結果中看出來,果然那個遊標在一條一條向下移動

既然在操作存儲在內存中的對象時候,遊標會移動,能不能讓遊標向上移動,或者移動到指定位置呢?當然可以,這就是scroll()

>>> print cur.fetchone()
(5L, u'docker', 10L, u'[email protected]')
>>> cur.scroll(-3)
>>> print cur.fetchone()
(3L, u'facebook', 18L, u'[email protected]')
>>> cur.scroll(1)
>>> print cur.fetchone()
(5L, u'docker', 10L, u'[email protected]')>>>

果然,這個函數能夠移動遊標,不過請仔細觀察,上面的方式是讓遊標相對與當前位置向上或者向下移動。即:

cur.scroll(n),或者,cur.scroll(n,"relative"):意思是相對當前位置向上或者向下移動,n 為正數,表示向下(向前),n 為負數,表示向上(向後)

還有一種方式,可以實現“絕對”移動,不是“相對”移動:增加一個參數"absolute"

特別提醒看官註意的是,在 Python 中,序列對象是的順序是從 0 開始的。

>>> cur.scroll(1,"absolute")               回到序號1,指向第2條數據
>>> print cur.fetchone()
(2L, u'google', 25L, u'[email protected]')
>>> 
 
>>> cur.scroll(0,"absolute")               回到序號0,指向第1條數據
>>> print cur.fetchone()
(1L, u'lulu', 18L, u'[email protected]')
>>>

承接上面操作,繼續

>>> print cur.fetchmany(3)
((2L, u'google', 25L, u'[email protected]'), (3L, u'facebook', 18L, u'[email protected]'), (4L, u'github', 20L, u'[email protected]'))
>>>

上面這個操作,就是實現了從當前位置(遊標指向 tuple 的序號為 1 的位置,即第二條記錄)開始,含當前位置,向下列出 3 條記錄。

更新數據

更新和插入一樣,都需要commit()來提交保存。

>>> cur.execute("update user set name=%s where id=5",("apple",))
1L
>>> cur.execute("select * from user where id=5")
1L
>>> print cur.fetchone()
(5L, u'apple', 10L, u'[email protected]')
>>>

提交更新

>>> conn.commit()
>>>

最後,關閉遊標,關閉連接對象

>>> cur.close()
>>> conn.close()
>>>


Python操作數據庫之 MySQL