什么是MySQLdb?
MySQLdb是用于Python鏈接Mysql數(shù)據(jù)庫(kù)的接口玉吁,它實(shí)現(xiàn)了Python數(shù)據(jù)庫(kù)API規(guī)范V2.0呀舔,基于MySQL C API上建立的左敌。
如何安裝MySQLdb?
為了用DB-API編寫MySQL腳本始苇,必須確保已經(jīng)安裝了MySQL绰沥。復(fù)制以下代碼,并執(zhí)行:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
如果執(zhí)行后的輸出結(jié)果如下所示蔚万,意味著你沒(méi)有安裝MySQLdb模塊:
Traceback(most recent calllast):
File"test.py",line3,in
importMySQLdb
ImportError:NomodulenamedMySQLdb
安裝MySQLdb岭妖,請(qǐng)?jiān)L問(wèn)http://sourceforge.net/projects/mysql-python,(Linux平臺(tái)可以訪問(wèn):https://pypi.python.org/pypi/MySQL-python)從這里可選擇適合您的平臺(tái)的安裝包反璃,分為預(yù)編譯的二進(jìn)制文件和源代碼安裝包昵慌。
如果您選擇二進(jìn)制文件發(fā)行版本的話,安裝過(guò)程基本安裝提示即可完成淮蜈。如果從源代碼進(jìn)行安裝的話斋攀,則需要切換到MySQLdb發(fā)行版本的頂級(jí)目錄,并鍵入下列命令:
$ gunzipMySQL-python-1.2.2.tar.gz
$ tar-xvfMySQL-python-1.2.2.tar
$ cdMySQL-python-1.2.2
$ python setup.py build
$ python setup.py install
注意:請(qǐng)確保您有root權(quán)限來(lái)安裝上述模塊梧田。
數(shù)據(jù)庫(kù)連接
連接數(shù)據(jù)庫(kù)前淳蔼,請(qǐng)先確認(rèn)以下事項(xiàng):
·您已經(jīng)創(chuàng)建了數(shù)據(jù)庫(kù)TESTDB.
·在TESTDB數(shù)據(jù)庫(kù)中您已經(jīng)創(chuàng)建了表EMPLOYEE
·EMPLOYEE表字段為FIRST_NAME, LAST_NAME, AGE, SEX和INCOME。
·連接數(shù)據(jù)庫(kù)TESTDB使用的用戶名為"testuser"裁眯,密碼為"test123",你可以可以自己設(shè)定或者直接使用root用戶名及其密碼鹉梨,Mysql數(shù)據(jù)庫(kù)用戶授權(quán)請(qǐng)使用Grant命令。
·在你的機(jī)子上已經(jīng)安裝了Python MySQLdb模塊穿稳。
·如果您對(duì)sql語(yǔ)句不熟悉存皂,可以訪問(wèn)SQL基礎(chǔ)教程
實(shí)例:
以下實(shí)例鏈接Mysql的TESTDB數(shù)據(jù)庫(kù):
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
#打開(kāi)數(shù)據(jù)庫(kù)連接
db=MySQLdb.connect("localhost","testuser","test123","TESTDB")
#使用cursor()方法獲取操作游標(biāo)
cursor=db.cursor()
#使用execute方法執(zhí)行SQL語(yǔ)句
cursor.execute("SELECT VERSION()")
#使用fetchone()方法獲取一條數(shù)據(jù)庫(kù)。
data=cursor.fetchone()
print"Database version : %s "%data
#關(guān)閉數(shù)據(jù)庫(kù)連接
db.close()
執(zhí)行以上腳本輸出結(jié)果如下:
Databaseversion:5.0.45
創(chuàng)建數(shù)據(jù)庫(kù)表
如果數(shù)據(jù)庫(kù)連接存在我們可以使用execute()方法來(lái)為數(shù)據(jù)庫(kù)創(chuàng)建表逢艘,如下所示創(chuàng)建表EMPLOYEE:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
#打開(kāi)數(shù)據(jù)庫(kù)連接
db=MySQLdb.connect("localhost","testuser","test123","TESTDB")
#使用cursor()方法獲取操作游標(biāo)
cursor=db.cursor()
#如果數(shù)據(jù)表已經(jīng)存在使用execute()方法刪除表旦袋。
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
#創(chuàng)建數(shù)據(jù)表SQL語(yǔ)句
sql="""CREATE TABLE EMPLOYEE (
FIRST_NAMECHAR(20) NOT NULL,
LAST_NAMECHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor.execute(sql)
#關(guān)閉數(shù)據(jù)庫(kù)連接
db.close()
數(shù)據(jù)庫(kù)插入操作
以下實(shí)例使用執(zhí)行SQL INSERT語(yǔ)句向表EMPLOYEE插入記錄:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
#打開(kāi)數(shù)據(jù)庫(kù)連接
db=MySQLdb.connect("localhost","testuser","test123","TESTDB")
#使用cursor()方法獲取操作游標(biāo)
cursor=db.cursor()
# SQL插入語(yǔ)句
sql="""INSERT INTOEMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M',2000)"""
try:
#執(zhí)行sql語(yǔ)句
cursor.execute(sql)
#提交到數(shù)據(jù)庫(kù)執(zhí)行
db.commit()
except:
# Rollback in case there
is any error
db.rollback()
#關(guān)閉數(shù)據(jù)庫(kù)連接
db.close()
以上例子也可以寫成如下形式:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
#打開(kāi)數(shù)據(jù)庫(kù)連接
db=MySQLdb.connect("localhost","testuser","test123","TESTDB")
#使用cursor()方法獲取操作游標(biāo)
cursor=db.cursor()
# SQL插入語(yǔ)句
sql="INSERT INTO EMPLOYEE(FIRST_NAME, \
LAST_NAME, AGE, SEX, INCOME) \
VALUES ('%s', '%s', '%d', '%c', '%d')"%\
('Mac','Mohan',20,'M',2000)
try:
#執(zhí)行sql語(yǔ)句
cursor.execute(sql)
#提交到數(shù)據(jù)庫(kù)執(zhí)行
db.commit()
except:
#發(fā)生錯(cuò)誤時(shí)回滾
db.rollback()
#關(guān)閉數(shù)據(jù)庫(kù)連接
db.close()
實(shí)例:
以下代碼使用變量向SQL語(yǔ)句中傳遞參數(shù):
..................................
user_id="test123"
password="password"
con.execute('insert into Login values("%s",
"%s")'%\
(user_id,password))
..................................
數(shù)據(jù)庫(kù)查詢操作
Python查詢Mysql使用fetchone()方法獲取單條數(shù)據(jù),使用fetchall()方法獲取多條數(shù)據(jù)。
·fetchone():該方法獲取下一個(gè)查詢結(jié)果集埋虹。結(jié)果集是一個(gè)對(duì)象
·fetchall():接收全部的返回結(jié)果行.
·rowcount:這是一個(gè)只讀屬性猜憎,并返回執(zhí)行execute()方法后影響的行數(shù)娩怎。
實(shí)例:
查詢EMPLOYEE表中salary(工資)字段大于1000的所有數(shù)據(jù):
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
#打開(kāi)數(shù)據(jù)庫(kù)連接
db=MySQLdb.connect("localhost","testuser","test123","TESTDB")
#使用cursor()方法獲取操作游標(biāo)
cursor=db.cursor()
# SQL查詢語(yǔ)句
sql="SELECT * FROM EMPLOYEE \
WHERE INCOME > '%d'"%(1000)
try:
#執(zhí)行SQL語(yǔ)句
cursor.execute(sql)
#獲取所有記錄列表
results=cursor.fetchall()
forrowinresults:
fname=row[0]
lname=row[1]
age=row[2]
sex=row[3]
income=row[4]
#打印結(jié)果
print"fname=%s,lname=%s,age=%d,sex=%s,income=%d"%\
(fname,lname,age,sex,income)
except:
print"Error: unable to fecth data"
#關(guān)閉數(shù)據(jù)庫(kù)連接
db.close()
以上腳本執(zhí)行結(jié)果如下:
fname=Mac,lname=Mohan,age=20,sex=M,income=2000
數(shù)據(jù)庫(kù)更新操作
更新操作用于更新數(shù)據(jù)表的的數(shù)據(jù)搔课,以下實(shí)例將EMPLOYEE表中的SEX字段為'M'的AGE字段遞增1:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
#打開(kāi)數(shù)據(jù)庫(kù)連接
db=MySQLdb.connect("localhost","testuser","test123","TESTDB")
#使用cursor()方法獲取操作游標(biāo)
cursor=db.cursor()
# SQL更新語(yǔ)句
sql="UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE
SEX = '%c'"%('M')
try:
#執(zhí)行SQL語(yǔ)句
cursor.execute(sql)
#提交到數(shù)據(jù)庫(kù)執(zhí)行
db.commit()
except:
#發(fā)生錯(cuò)誤時(shí)回滾
db.rollback()
#關(guān)閉數(shù)據(jù)庫(kù)連接
db.close()
刪除操作
刪除操作用于刪除數(shù)據(jù)表中的數(shù)據(jù),以下實(shí)例演示了刪除數(shù)據(jù)表EMPLOYEE中AGE大于20的所有數(shù)據(jù):
#!/usr/bin/python
# -*- coding: UTF-8 -*-
importMySQLdb
#打開(kāi)數(shù)據(jù)庫(kù)連接
db=MySQLdb.connect("localhost","testuser","test123","TESTDB")
#使用cursor()方法獲取操作游標(biāo)
cursor=db.cursor()
# SQL刪除語(yǔ)句
sql="DELETE FROM EMPLOYEE WHERE AGE >
'%d'"%(20)
try:
#執(zhí)行SQL語(yǔ)句
cursor.execute(sql)
#提交修改
db.commit()
except:
#發(fā)生錯(cuò)誤時(shí)回滾
db.rollback()
#關(guān)閉連接
db.close()
執(zhí)行事務(wù)
事務(wù)機(jī)制可以確保數(shù)據(jù)一致性。
事務(wù)應(yīng)該具有4個(gè)屬性:原子性爬泥、一致性柬讨、隔離性、持久性袍啡。這四個(gè)屬性通常稱為ACID特性踩官。
·原子性(atomicity)。一個(gè)事務(wù)是一個(gè)不可分割的工作單位境输,事務(wù)中包括的諸操作要么都做蔗牡,要么都不做。
·一致性(consistency)嗅剖。事務(wù)必須是使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)辩越。一致性與原子性是密切相關(guān)的。
·隔離性(isolation)信粮。一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾黔攒。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾强缘。
·持久性(durability)督惰。持續(xù)性也稱永久性(permanence),指一個(gè)事務(wù)一旦提交旅掂,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就應(yīng)該是永久性的赏胚。接下來(lái)的其他操作或故障不應(yīng)該對(duì)其有任何影響。
Python DB API 2.0的事務(wù)提供了兩個(gè)方法commit或rollback商虐。
實(shí)例:
# SQL刪除記錄語(yǔ)句
sql="DELETE FROM EMPLOYEE WHERE AGE >
'%d'"%(20)
try:
#執(zhí)行SQL語(yǔ)句
cursor.execute(sql)
#向數(shù)據(jù)庫(kù)提交
db.commit()
except:
#發(fā)生錯(cuò)誤時(shí)回滾
db.rollback()
對(duì)于支持事務(wù)的數(shù)據(jù)庫(kù)栅哀,在Python數(shù)據(jù)庫(kù)編程中,當(dāng)游標(biāo)建立之時(shí)称龙,就自動(dòng)開(kāi)始了一個(gè)隱形的數(shù)據(jù)庫(kù)事務(wù)留拾。
commit()方法游標(biāo)的所有更新操作,rollback()方法回滾當(dāng)前游標(biāo)的所有操作鲫尊。每一個(gè)方法都開(kāi)始了一個(gè)新的事務(wù)痴柔。
錯(cuò)誤處理
DB API中定義了一些數(shù)據(jù)庫(kù)操作的錯(cuò)誤及異常,下表列出了這些錯(cuò)誤和異常:
異常
描述
Warning
當(dāng)有嚴(yán)重警告時(shí)觸發(fā)疫向,例如插入數(shù)據(jù)是被截?cái)嗟鹊瓤任怠1仨毷荢tandardError的子類。
Error
警告以外所有其他錯(cuò)誤類搔驼。必須是StandardError的子類谈火。
InterfaceError
當(dāng)有數(shù)據(jù)庫(kù)接口模塊本身的錯(cuò)誤(而不是數(shù)據(jù)庫(kù)的錯(cuò)誤)發(fā)生時(shí)觸發(fā)。必須是Error的子類舌涨。
DatabaseError
和數(shù)據(jù)庫(kù)有關(guān)的錯(cuò)誤發(fā)生時(shí)觸發(fā)糯耍。必須是Error的子類。
DataError
當(dāng)有數(shù)據(jù)處理時(shí)的錯(cuò)誤發(fā)生時(shí)觸發(fā),例如:除零錯(cuò)誤温技,數(shù)據(jù)超范圍等等革为。必須是DatabaseError的子類。
OperationalError
指非用戶控制的舵鳞,而是操作數(shù)據(jù)庫(kù)時(shí)發(fā)生的錯(cuò)誤震檩。例如:連接意外斷開(kāi)、數(shù)據(jù)庫(kù)名未找到蜓堕、事務(wù)處理失敗抛虏、內(nèi)存分配錯(cuò)誤等等操作數(shù)據(jù)庫(kù)是發(fā)生的錯(cuò)誤。必須是DatabaseError的子類套才。
IntegrityError
完整性相關(guān)的錯(cuò)誤嘉蕾,例如外鍵檢查失敗等。必須是DatabaseError子類霜旧。
InternalError
數(shù)據(jù)庫(kù)的內(nèi)部錯(cuò)誤错忱,例如游標(biāo)(cursor)失效了、事務(wù)同步失敗等等挂据。必須是DatabaseError子類以清。
ProgrammingError
程序錯(cuò)誤,例如數(shù)據(jù)表(table)沒(méi)找到或已存在崎逃、SQL語(yǔ)句語(yǔ)法錯(cuò)誤掷倔、參數(shù)數(shù)量錯(cuò)誤等等。必須是DatabaseError的子類个绍。
NotSupportedError
不支持錯(cuò)誤勒葱,指使用了數(shù)據(jù)庫(kù)不支持的函數(shù)或API等。例如在連接對(duì)象上使用.rollback()函數(shù)巴柿,然而數(shù)據(jù)庫(kù)并不支持事務(wù)或者事務(wù)已關(guān)閉凛虽。必須是DatabaseError的子類。