使用環境:Windows+python3.4+MySQL5.5+Navicat
一、創建連接
1.准備工作,想要使用Python操作MySQL,首先需要安裝MySQL-Python的包,在Python 3.x下,該包已經改名為MySQLClient。可以使用pip方式安裝:
pip install MySQLClient
或者下載包文件,進行安裝也可以。
2.Python使用MySQL的流程:

3.啟動MySQL服務器:以管理員身份啟動“cmd”,輸入命令:’net start mysql‘
Python中使用MySQL導入方法:import MySQLdb
4.創建Connection
Connection:創建了Python客戶端與數據庫之間的網絡通路。他的參數如下
| 參數名 | 類型 | 說明 |
| host | String | MySQL的服務器地址 |
| port | int | MySQL的端口號 |
| user | String | 用戶名 |
| passwd | String | 密碼 |
| db | String | 使用的數據庫 |
| charset | String | 連接字符集 |
Connection支持的方法:
| 方法名 | 說明 |
| cursor() | 創建並且返回游標 |
| commit() | 提交當前事物 |
| rollback() | 回滾當前事物r() |
| close() | 關閉Connection |
5.獲取Cursor.
Cursor:游標對象,用於執行查詢和獲取結果,它支持的方法如下:
| 方法名 | 說明 |
| execute() | 用於執行一個數據庫的查詢命令 |
| fetchone() | 獲取結果集中的下一行 |
| fetchmany(size) |
獲取結果集中的下(size)行 |
| fetchall() | 獲取結果集中剩下的所有行 |
| rowcount | 最近一次execute返回數據/影響的行數 |
| close() | 關閉游標 |
下面我們在Python中創建一個實例:
import MySQLdb conn=MySQLdb.connect(host='127.0.0.1',port=3306,user='root',passwd='199331',db='test',charset='utf8') cursor=conn.cursor() print(conn) print(cursor) cursor.close() conn.close()
運行程序結果如下:
從結果中我們可以看見成功創建了一個Connection和Cursor對象。
二、建立數據庫,進行一些簡單操作
1.簡單的創建一個’user‘表,並且插入一些數據。user表中只有兩個字段:userid和username。代碼如下:
import MySQLdb conn=MySQLdb.connect(host='127.0.0.1',port=3306,user='root',passwd='199331',db='test',charset='utf8') cur=conn.cursor() cur.execute(""" create table if not EXISTS user ( userid int(11) PRIMARY KEY , username VARCHAR(20) ) """) for i in range(1,10): cur.execute("insert into user(userid,username) values('%d','%s')" %(int(i),'name'+str(i))) conn.commit() cur.close() conn.close()
我們用Navicat打開數據庫,查看一下結果,,可以看到成功創建表,並且插入了十個數據。
2.我們操作一下Cursor里面的一些方法。
execute()方法:執行SQL,將一個結果從數據庫獲取到客戶端
fetch*()方法:移動rownumber,返回數據。
例如我們有如下代碼:
sql='select * from user' cursor.execute(sql) print(cursor.rowcount) rs=cursor.fetchone() print(rs) rs=cursor.fetchmany(3) print(rs)
rs=cursor.fetchall()
print(rs)
結果如下:

我們可以看出執行查詢全部數據后,rowcount為10
執行fetchone()方法后返回一個數據,執行fetchmany(3)后返回3條數據,執行fetchall()后返回剩下的所有數據。
再有如下代碼:
res=cursor.fetchall()
for row in res:
print('userid=%s,userna=%s' %row)
此時的執行結果為:

3.上面介紹的便是數據庫中常說的Select操作,下面我們介紹數據的更新,即:insert、update、delete操作。值得注意的是在這部分操作時需要注意的是是否數據發生異常,如果數據沒有發生異常,我們便可以直接使用commit()進行提交(注:如沒有使用commit,則數據庫不會發生任何變化)。但是如果出現了異常,那么久需要使用rollback()進行回滾。
3.1先來看一個沒有異常,正常提交的例子:
sql_insert='insert into user(userid,username) values(10,"name10")' sql_update='update user set username="name91" where userid=9' sql_delete='delete from user where userid=3' cursor.execute(sql_insert) print(cursor.rowcount) cursor.execute(sql_update) print(cursor.rowcount) cursor.execute(sql_delete) print(cursor.rowcount)
conn.commit()
上面的操作即是:添加一條(10,’name10‘)的數據、將userid=9的username修改為’name91‘,刪除userid=3的數據,執行上面代碼后我們來用Navicat查看一下數據:
從結果可以看到代碼執行正常。
3.2.再來看一個有異常的數據
sql_insert='insert into user(userid,username) values(10,"name10")'
sql_update='update user set username="name91" where userid=9'
# sql_delete='delete from user where userid=3'
# ##error
sql_delete='delete from user where useri=3'
try:
cursor.execute(sql_insert)
print(cursor.rowcount)
cursor.execute(sql_update)
print(cursor.rowcount)
cursor.execute(sql_delete)
print(cursor.rowcount)
except Exception as e:
print(e)
conn.rollback()
這里的insert和update操作一樣,只不過把delete里面的userid字段錯誤的寫成了useri,執行代碼:

可以看到顯示出異常,這時我們來看一下數據庫數據:
數據沒有任何改變。這就是rollback()的作用
因此,我們以后再寫增刪改查操作時,最好把操作放入一個try控制塊中,來避免一些不必要的錯誤。
下面是一個銀行轉賬的實例:
#-*-encoding:utf-8 -*-
import MySQLdb
conn=MySQLdb.connect(host='127.0.0.1',port=3306,user='root',passwd='199331',db='test',charset='utf8')
cur=conn.cursor()
##創建數據表
cur.execute("""
create table if not EXISTS account(
accid int(10) PRIMARY KEY ,
money int(10)
)
""")
###插入兩行數據
cur.execute('insert into account(accid,money) VALUES (1,110)')
cur.execute('insert into account(accid,money) VALUES (2,10)')
conn.commit()
cur.close()
conn.close()
#-*- encoding:utf-8 -*-
import sys
import MySQLdb
class TransferMoney(object):
def __init__(self,conn):
self.conn=conn
def check_acct_available(self,accid):
cursor=self.conn.cursor()
try:
sql='select * from account where accid=%s' %accid
cursor.execute(sql)
print('check_acct_available'+sql)
rs=cursor.fetchall()
if len(rs)!=1:
raise Exception('賬號%s 不存在' %accid)
finally:
cursor.close()
def has_enough_money(self,accid,money):
cursor=self.conn.cursor()
try:
sql='select * from account where accid=%s and money>%s' %(accid,money)
cursor.execute(sql)
print('check_money_available'+sql)
rs=cursor.fetchall()
if len(rs)!=1:
raise Exception('賬號%s 沒有足夠錢' %accid)
finally:
cursor.close()
def reduce_money(self,accid,money):
cursor=self.conn.cursor()
try:
sql='update account set money=money-%s where accid=%s' %(money,accid)
cursor.execute(sql)
print('reduce money'+sql)
rs=cursor.fetchall()
if cursor.rowcount!=1:
raise Exception('賬號%s 減款失敗' %accid)
finally:
cursor.close()
def add_money(self,accid,money):
cursor=self.conn.cursor()
try:
sql='update account set money=money+%s where accid=%s' %(money,accid)
cursor.execute(sql)
print('reduce money'+sql)
rs=cursor.fetchall()
if cursor.rowcount!=1:
raise Exception('賬號%s 加款失敗' %accid)
finally:
cursor.close()
def transfer(self,source_accid,target_accid,money):
###檢測兩個賬號是否可用
try:
self.check_acct_available(source_accid)
self.check_acct_available(target_accid)
####檢測付款人是否有足夠的錢
self.has_enough_money(source_accid,money)
self.reduce_money(source_accid,money)
self.add_money(target_accid,money)
self.conn.commit()
except Exception as e:
self.conn.rollback()
raise e
if __name__=='__main__':
source_accid=sys.argv[1]
target_accid=sys.argv[2]
money=sys.argv[3]
conn=MySQLdb.connect(host='127.0.0.1',port=3306,user='root',passwd='199331',db='test',charset='utf8')
tr_money=TransferMoney(conn)
try:
tr_money.transfer(source_accid,target_accid,money)
except Exception as e:
print('出現問題'+str(e))
finally:
conn.close()
