python3操作MySQL數據庫
阿新 • • 發佈:2017-06-13
更新數據 lin 用戶 head 比較 for man final bject
這是python3下的MySQL基本操作。其他類型的數據庫用法基本一樣。就是庫的名字不同。因為python官方很早之前就規定了數據庫第三方庫的借口,來避免API混亂的情況。
安裝與準備
這是python3的庫,所以windows下安裝不會像python2那樣各種奇葩VC錯誤。是比較方便的傻瓜安裝。
- Windows平臺下:
py -3 -m pip install PyMySQL
- Linux:
python3 pip install PyMySQL
當然,引入的時候:import pymysql
數據庫連接對象connection
Function | 描述 |
---|---|
connection | 創建connection對象 |
cursor() | 使用該鏈接創建+返回遊標 |
commit() | 提交當前事務 |
rollback() | 回滾當前十五 |
close() | 關閉連接 |
介紹一下connection的參數
- host mysql服務器地址
- port 數字類型 端口
- user 用戶名
- passwd 密碼
- db 數據庫名稱
- charset 連接編碼,需要顯式指明編碼方式
上一段代碼示例:
conn = pymysql.Connect(host=‘127.0.0.1‘,port=3306,user=‘root‘,passwd=‘dyx240030‘,db=‘imooc‘,charset=‘utf8‘) cursor = conn.cursor() print(conn) print(cursor) cursor.close() conn.close()
OUT:
<pymysql.connections.Connection object at 0x00000051C15BFDA0>
<pymysql.cursors.Cursor object at 0x00000051C15BFD68>
數據庫遊標對象cursor
Function | 描述 |
---|---|
execute(op[,args]) | 執行一個數據庫查詢和命令 |
fetchone() | 取得結果集下一行 |
fetchmany(size) | 取得結果集size行 |
fetchall() | 取得結果集剩下所有行 |
rowcount | 最近一次execute返回數據的行數或影響行數 |
close() | 關閉cursor |
代碼實現:
conn = pymysql.Connect(host=‘127.0.0.1‘,port=3306,user=‘root‘,passwd=‘dyx240030‘,db=‘imooc‘,charset=‘utf8‘)
cursor = conn.cursor()
sql = "select * from user"
cursor.execute(sql)
print("cursor.excute:",cursor.rowcount)
rs = cursor.fetchone()
print("rs:",rs)
for each in cursor.fetchmany(2):
print(each)
print()
for each in cursor.fetchall():
print(each)
OUT:
cursor.excute: 4
rs: (‘1‘, ‘name1‘)
(‘2‘, ‘name2‘)
(‘3‘, ‘name3‘)
(‘4‘, ‘name4‘)
更新數據庫insert/update/delete
不同於select操作,這三個操作修改了數據庫內容,所以需要commit(),否則數據庫沒有做相應的更改,但是也不會報錯。
按照一般的思路,一般是以下套路:
- 關閉自動commit:conn.autocommit(False)
- 出現:conn.rowback()回滾
- 未出現:conn.commit()
下面這段腳本,實現insert/update/delete操作。其實這種檢錯模式不對,這裏只做簡單raise,後面有更好的方法。
conn = pymysql.Connect(host=‘127.0.0.1‘,port=3306,user=‘root‘,passwd=‘dyx240030‘,db=‘imooc‘,charset=‘utf8‘)
conn.autocommit(False)
cursor = conn.cursor()
sqlInsert = "insert into user(userid,username) values(‘6‘,‘name6‘)"
sqlUpdate = "update user set username=‘name41‘ where userd=‘4‘"
sqlDelete = "delete from user where userid=‘1‘"
try:
cursor.execute(sqlInsert)
print(cursor.rowcount)
cursor.execute(sqlUpdate)
print(cursor.rowcount)
cursor.execute(sqlDelete)
print(cursor.rowcount)
conn.commit()
except Exception as e:
print("Reason:",e)
conn.rollback()
cursor.close()
cursor.close()
[OUT]:
1
Reason: (1054, "Unknown column ‘userd‘ in ‘where clause‘")
實例 銀行轉賬
可以看一下類思想的SQL操作,其中之前提到過的高級報錯模式用到了之前看似無用的
rowcount
函數,通過查看操作對於數據庫的影響來檢錯。
import os
import sys
import pymysql
class transferMoney(object):
def __init__(self,conn):
self.conn = conn
def transfer(self,sourceID,targetID,money):
# 其他函數中若是有錯會拋出異常而被檢測到。
try:
self.checkIdAvailable(sourceID)
self.checkIdAvailable(targetID)
self.ifEnoughMoney(sourceID,money)
self.reduceMoney(sourceID,money)
self.addMoney(targetID,money)
self.conn.commit()
except Exception as e:
self.conn.rollback()
raise e
def checkIdAvailable(self,ID):
cursor = self.conn.cursor()
try:
sql = "select * from account where id = %d" % ID #select語句判斷可以用len(rs)
cursor.execute(sql)
rs= cursor.fetchall()
if len(rs) != 1:# 數據庫類思想的報錯模式,檢查操作對數據庫的影響條目。沒有達到目標,拋出異常
raise Exception("賬號 %d 不存在"%ID)
finally:
cursor.close()
def ifEnoughMoney(self,ID,money):
cursor = self.conn.cursor()
try:
sql = "select * from account where id = %d and money>=%d" % (ID,money)
cursor.execute(sql)
rs= cursor.fetchall()
if len(rs) != 1:
raise Exception("賬號 %d 不存在 %d Yuan"%(ID,money))
finally:
cursor.close()
def reduceMoney(self,ID,money):
cursor = self.conn.cursor()
try:
sql = "update account set money = money-%d where id=%d"%(money,ID)
cursor.execute(sql)
if cursor.rowcount != 1:
raise Exception("失敗減錢")
finally:
cursor.close()
def addMoney(self,ID,money):
cursor = self.conn.cursor()
try:
sql = "update account set money = money+%d where id=%d"%(money,ID)
cursor.execute(sql)
if cursor.rowcount != 1:
raise Exception("失敗加款")
finally:
cursor.close()
if __name__=="__main__":
if len(sys.argv)>=2:
sourceID = int(sys.argv[1])
targetID = int(sys.argv[2])
money = int(sys.argv[3])
conn = pymysql.Connect(host=‘127.0.0.1‘,port=3306,user=‘root‘,passwd=‘dyx240030‘,db=‘imooc‘,charset=‘utf8‘)
trMoney = transferMoney(conn)
try:
trMoney.transfer(sourceID,targetID,money)
except Exception as e:
print("出現問題"+str(e))
finally:
conn.close()
我踩過的坑。。。(這裏是Python3哦)
‘NoneType‘ object has no attribute ‘encoding‘ ,之前指明的charset必須是"UTF8",不是"utf-8"/"UTF-8"
MySQL語句後面必須有‘;‘,否則不會報錯,也難以發現
數據庫insert/update/delete操作需要commit()
在構造命令的時候,註意用 " 包裹起來,因為SQL語句字符串需要 ‘ 包裹。所以," 比較簡單的避免歧義。
python3操作MySQL數據庫