Python3 MySQL 數(shù)據(jù)庫連接
本文我們?yōu)榇蠹医榻B Python3 使用?PyMySQL?連接數(shù)據(jù)庫,并實現(xiàn)簡單的增刪改查。
什么是 PyMySQL?
PyMySQL 是在 Python3.x 版本中用于連接 MySQL 服務(wù)器的一個庫,Python2 中則使用mysqldb。
PyMySQL 遵循 Python 數(shù)據(jù)庫 API v2.0 規(guī)范,并包含了 pure-Python MySQL 客戶端庫。
PyMySQL 安裝
在使用 PyMySQL 之前,我們需要確保 PyMySQL 已安裝。
PyMySQL 下載地址:https://github.com/PyMySQL/PyMySQL。
如果還未安裝,我們可以使用以下命令安裝最新版的 PyMySQL:
$ pip install PyMySQL
如果你的系統(tǒng)不支持 pip 命令,可以使用以下方式安裝:
1、使用 git 命令下載安裝包安裝(你也可以手動下載):
$ git clone https://github.com/PyMySQL/PyMySQL
$ cd PyMySQL/
$ python3 setup.py install
2、如果需要制定版本號,可以使用 curl 命令來安裝:
$ # X.X 為 PyMySQL 的版本號
$ curl -L https://github.com/PyMySQL/PyMySQL/tarball/pymysql-X.X | tar xz
$ cd PyMySQL*
$ python3 setup.py install
$ # 現(xiàn)在你可以刪除 PyMySQL* 目錄
注意:請確保您有 root 權(quán)限來安裝上述模塊。
安裝的過程中可能會出現(xiàn)"ImportError: No module named setuptools"的錯誤提示,意思是你沒有安裝setuptools,你可以訪問setuptools · PyPI?找到各個系統(tǒng)的安裝方法。
Linux 系統(tǒng)安裝實例:
$ wget https://bootstrap.pypa.io/ez_setup.py $ python3 ez_setup.py
數(shù)據(jù)庫連接
連接數(shù)據(jù)庫前,請先確認(rèn)以下事項:
- 您已經(jīng)創(chuàng)建了數(shù)據(jù)庫 TESTDB.
- 在 TESTDB 數(shù)據(jù)庫中您已經(jīng)創(chuàng)建了表 EMPLOYEE
- EMPLOYEE 表字段為 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。
- 連接數(shù)據(jù)庫 TESTDB 使用的用戶名為 "testuser" ,密碼為 "test123",你可以可以自己設(shè)定或者直接使用 root 用戶名及其密碼,Mysql 數(shù)據(jù)庫用戶授權(quán)請使用 Grant 命令。
- 在你的機子上已經(jīng)安裝了 Python MySQLdb 模塊。
- 如果您對 sql 語句不熟悉,可以訪問我們的?SQL教程
實例:
以下實例鏈接 Mysql 的 TESTDB 數(shù)據(jù)庫:
#!/usr/bin/python3 import pymysql # 打開數(shù)據(jù)庫連接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用 cursor() 方法創(chuàng)建一個游標(biāo)對象 cursor cursor = db.cursor() # 使用 execute() 方法執(zhí)行 SQL 查詢 cursor.execute("SELECT VERSION()") # 使用 fetchone() 方法獲取單條數(shù)據(jù). data = cursor.fetchone() print ("Database version : %s " % data) # 關(guān)閉數(shù)據(jù)庫連接 db.close()
執(zhí)行以上腳本輸出結(jié)果如下:
Database version : 5.5.20-log
創(chuàng)建數(shù)據(jù)庫表
如果數(shù)據(jù)庫連接存在我們可以使用 execute() 方法來為數(shù)據(jù)庫創(chuàng)建表,如下所示創(chuàng)建表EMPLOYEE:
#!/usr/bin/python3 import pymysql # 打開數(shù)據(jù)庫連接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用 cursor() 方法創(chuàng)建一個游標(biāo)對象 cursor cursor = db.cursor() # 使用 execute() 方法執(zhí)行 SQL,如果表存在則刪除 cursor.execute("DROP TABLE IF EXISTS EMPLOYEE") # 使用預(yù)處理語句創(chuàng)建表 sql = """CREATE TABLE EMPLOYEE ( FIRST_NAME CHAR(20) NOT NULL, LAST_NAME CHAR(20), AGE INT, SEX CHAR(1), INCOME FLOAT )""" cursor.execute(sql) # 關(guān)閉數(shù)據(jù)庫連接 db.close()
數(shù)據(jù)庫插入操作
以下實例使用執(zhí)行 SQL INSERT 語句向表 EMPLOYEE 插入記錄:
#!/usr/bin/python3 import pymysql # 打開數(shù)據(jù)庫連接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用cursor()方法獲取操作游標(biāo) cursor = db.cursor() # SQL 插入語句 sql = """INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('Mac', 'Mohan', 20, 'M', 2000)""" try: # 執(zhí)行sql語句 cursor.execute(sql) # 提交到數(shù)據(jù)庫執(zhí)行 db.commit() except: # 如果發(fā)生錯誤則回滾 db.rollback() # 關(guān)閉數(shù)據(jù)庫連接 db.close()
以上例子也可以寫成如下形式:
#!/usr/bin/python3 import pymysql # 打開數(shù)據(jù)庫連接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用cursor()方法獲取操作游標(biāo) cursor = db.cursor() # SQL 插入語句 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語句 cursor.execute(sql) # 執(zhí)行sql語句 db.commit() except: # 發(fā)生錯誤時回滾 db.rollback() # 關(guān)閉數(shù)據(jù)庫連接 db.close()
以下代碼使用變量向 SQL 語句中傳遞參數(shù):
.................................. user_id = "test123" password = "password" con.execute('insert into Login values("%s", "%s")' % \ (user_id, password)) ..................................
數(shù)據(jù)庫查詢操作
Python 查詢 Mysql 使用 fetchone() 方法獲取單條數(shù)據(jù), 使用 fetchall() 方法獲取多條數(shù)據(jù)。
- fetchone():?該方法獲取下一個查詢結(jié)果集。結(jié)果集是一個對象
- fetchall():?接收全部的返回結(jié)果行.
- rowcount:?這是一個只讀屬性,并返回執(zhí)行 execute() 方法后影響的行數(shù)。
實例:
查詢 EMPLOYEE 表中 salary(工資)字段大于 1000 的所有數(shù)據(jù):
#!/usr/bin/python3 import pymysql # 打開數(shù)據(jù)庫連接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用cursor()方法獲取操作游標(biāo) cursor = db.cursor() # SQL 查詢語句 sql = "SELECT * FROM EMPLOYEE \ WHERE INCOME > '%d'" % (1000) try: # 執(zhí)行SQL語句 cursor.execute(sql) # 獲取所有記錄列表 results = cursor.fetchall() for row in results: 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ù)庫連接 db.close()
以上腳本執(zhí)行結(jié)果如下:
fname=Mac, lname=Mohan, age=20, sex=M, income=2000
數(shù)據(jù)庫更新操作
更新操作用于更新數(shù)據(jù)表的的數(shù)據(jù),以下實例將 TESTDB 表中的 SEX 字段全部修改為 'M',AGE 字段遞增 1:
#!/usr/bin/python3 import pymysql # 打開數(shù)據(jù)庫連接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用cursor()方法獲取操作游標(biāo) cursor = db.cursor() # SQL 更新語句 sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M') try: # 執(zhí)行SQL語句 cursor.execute(sql) # 提交到數(shù)據(jù)庫執(zhí)行 db.commit() except: # 發(fā)生錯誤時回滾 db.rollback() # 關(guān)閉數(shù)據(jù)庫連接 db.close()
刪除操作
刪除操作用于刪除數(shù)據(jù)表中的數(shù)據(jù),以下實例演示了刪除數(shù)據(jù)表 EMPLOYEE 中 AGE 大于 20 的所有數(shù)據(jù):
#!/usr/bin/python3 import pymysql # 打開數(shù)據(jù)庫連接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用cursor()方法獲取操作游標(biāo) cursor = db.cursor() # SQL 刪除語句 sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20) try: # 執(zhí)行SQL語句 cursor.execute(sql) # 提交修改 db.commit() except: # 發(fā)生錯誤時回滾 db.rollback() # 關(guān)閉連接 db.close()
執(zhí)行事務(wù)
事務(wù)機制可以確保數(shù)據(jù)一致性。
事務(wù)應(yīng)該具有 4 個屬性:原子性、一致性、隔離性、持久性。這四個屬性通常稱為 ACID 特性。
- 原子性(atomicity)。一個事務(wù)是一個不可分割的工作單位,事務(wù)中包括的諸操作要么都做,要么都不做。
- 一致性(consistency)。事務(wù)必須是使數(shù)據(jù)庫從一個一致性狀態(tài)變到另一個一致性狀態(tài)。一致性與原子性是密切相關(guān)的。
- 隔離性(isolation)。一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾。
- 持久性(durability)。持續(xù)性也稱永久性(permanence),指一個事務(wù)一旦提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就應(yīng)該是永久性的。接下來的其他操作或故障不應(yīng)該對其有任何影響。
Python DB API 2.0 的事務(wù)提供了兩個方法 commit 或 rollback。
實例
# SQL刪除記錄語句 sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20) try: # 執(zhí)行SQL語句 cursor.execute(sql) # 向數(shù)據(jù)庫提交 db.commit() except: # 發(fā)生錯誤時回滾 db.rollback()
對于支持事務(wù)的數(shù)據(jù)庫, 在 Python 數(shù)據(jù)庫編程中,當(dāng)游標(biāo)建立之時,就自動開始了一個隱形的數(shù)據(jù)庫事務(wù)。
commit() 方法游標(biāo)的所有更新操作,rollback()方法回滾當(dāng)前游標(biāo)的所有操作。每一個方法都開始了一個新的事務(wù)。
錯誤處理
DB API 中定義了一些數(shù)據(jù)庫操作的錯誤及異常,下表列出了這些錯誤和異常:
異常 | 描述 |
---|---|
Warning | 當(dāng)有嚴(yán)重警告時觸發(fā),例如插入數(shù)據(jù)是被截斷等等。必須是 StandardError 的子類。 |
Error | 警告以外所有其他錯誤類。必須是 StandardError 的子類。 |
InterfaceError | 當(dāng)有數(shù)據(jù)庫接口模塊本身的錯誤(而不是數(shù)據(jù)庫的錯誤)發(fā)生時觸發(fā)。 必須是 Error 的子類。 |
DatabaseError | 和數(shù)據(jù)庫有關(guān)的錯誤發(fā)生時觸發(fā)。 必須是 Error 的子類。 |
DataError | 當(dāng)有數(shù)據(jù)處理時的錯誤發(fā)生時觸發(fā),例如:除零錯誤,數(shù)據(jù)超范圍等等。 必須是 DatabaseError 的子類。 |
OperationalError | 指非用戶控制的,而是操作數(shù)據(jù)庫時發(fā)生的錯誤。例如:連接意外斷開、 數(shù)據(jù)庫名未找到、事務(wù)處理失敗、內(nèi)存分配錯誤等等操作數(shù)據(jù)庫是發(fā)生的錯誤。 必須是 DatabaseError 的子類。 |
IntegrityError | 完整性相關(guān)的錯誤,例如外鍵檢查失敗等。必須是 DatabaseError 子類。 |
InternalError | 數(shù)據(jù)庫的內(nèi)部錯誤,例如游標(biāo)(cursor)失效了、事務(wù)同步失敗等等。 必須是 DatabaseError 子類。 |
ProgrammingError | 程序錯誤,例如數(shù)據(jù)表(table)沒找到或已存在、SQL 語句語法錯誤、 參數(shù)數(shù)量錯誤等等。必須是 DatabaseError 的子類。 |
NotSupportedError | 不支持錯誤,指使用了數(shù)據(jù)庫不支持的函數(shù)或API等。例如在連接對象上 使用 .rollback() 函數(shù),然而數(shù)據(jù)庫并不支持事務(wù)或者事務(wù)已關(guān)閉。 必須是 DatabaseError 的子類。 |
Python3 網(wǎng)絡(luò)編程
Python 提供了兩個級別訪問的網(wǎng)絡(luò)服務(wù)。:
- 低級別的網(wǎng)絡(luò)服務(wù)支持基本的 Socket,它提供了標(biāo)準(zhǔn)的 BSD Sockets API,可以訪問底層操作系統(tǒng) Socket 接口的全部方法。
- 高級別的網(wǎng)絡(luò)服務(wù)模塊 SocketServer, 它提供了服務(wù)器中心類,可以簡化網(wǎng)絡(luò)服務(wù)器的開發(fā)。
什么是 Socket?
Socket 又稱"套接字",應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求,使主機間或者一臺計算機上的進(jìn)程間可以通訊。
socket()函數(shù)
Python 中,我們用 socket()函數(shù)來創(chuàng)建套接字,語法格式如下:
socket.socket([family[, type[, proto]]])
參數(shù)
- family: 套接字家族可以使 AF_UNIX 或者 AF_INET
- type: 套接字類型可以根據(jù)是面向連接的還是非連接分為
SOCK_STREAM
或SOCK_DGRAM
- protocol: 一般不填默認(rèn)為0.
Socket 對象(內(nèi)建)方法
函數(shù) | 描述 |
---|---|
服務(wù)器端套接字 | |
s.bind() | 綁定地址(host,port)到套接字, 在 AF_INET 下,以元組(host,port)的形式表示地址。 |
s.listen() | 開始 TCP 監(jiān)聽。backlog 指定在拒絕連接之前,操作系統(tǒng)可以掛起的最大連接數(shù)量。該值至少為 1,大部分應(yīng)用程序設(shè)為 5 就可以了。 |
s.accept() | 被動接受 TCP 客戶端連接,(阻塞式)等待連接的到來 |
客戶端套接字 | |
s.connect() | 主動初始化 TCP 服務(wù)器連接,。一般 address 的格式為元組(hostname,port),如果連接出錯,返回 socket.error 錯誤。 |
s.connect_ex() | connect() 函數(shù)的擴(kuò)展版本,出錯時返回出錯碼,而不是拋出異常 |
公共用途的套接字函數(shù) | |
s.recv() | 接收 TCP 數(shù)據(jù),數(shù)據(jù)以字符串形式返回,bufsize指定要接收的最大數(shù)據(jù)量。flag 提供有關(guān)消息的其他信息,通??梢院雎?。 |
s.send() | 發(fā)送 TCP 數(shù)據(jù),將 string 中的數(shù)據(jù)發(fā)送到連接的套接字。返回值是要發(fā)送的字節(jié)數(shù)量,該數(shù)量可能小于 string 的字節(jié)大小。 |
s.sendall() | 完整發(fā)送 TCP 數(shù)據(jù),完整發(fā)送 TCP 數(shù)據(jù)。將 string 中的數(shù)據(jù)發(fā)送到連接的套接字,但在返回之前會嘗試發(fā)送所有數(shù)據(jù)。成功返回 None,失敗則拋出異常。 |
s.recvfrom() | 接收 UDP 數(shù)據(jù),與 recv() 類似,但返回值是(data,address)。其中 data 是包含接收數(shù)據(jù)的字符串,address 是發(fā)送數(shù)據(jù)的套接字地址。 |
s.sendto() | 發(fā)送 UDP 數(shù)據(jù),將數(shù)據(jù)發(fā)送到套接字,address 是形式為(ipaddr,port)的元組,指定遠(yuǎn)程地址。返回值是發(fā)送的字節(jié)數(shù)。 |
s.close() | 關(guān)閉套接字 |
s.getpeername() | 返回連接套接字的遠(yuǎn)程地址。返回值通常是元組(ipaddr,port)。 |
s.getsockname() | 返回套接字自己的地址。通常是一個元組(ipaddr,port) |
s.setsockopt(level,optname,value) | 設(shè)置給定套接字選項的值。 |
s.getsockopt(level,optname[.buflen]) | 返回套接字選項的值。 |
s.settimeout(timeout) | 設(shè)置套接字操作的超時期,timeout 是一個浮點數(shù),單位是秒。值為 None 表示沒有超時期。一般,超時期應(yīng)該在剛創(chuàng)建套接字時設(shè)置,因為它們可能用于連接的操作(如 connect()) |
s.gettimeout() | 返回當(dāng)前超時期的值,單位是秒,如果沒有設(shè)置超時期,則返回 None。 |
s.fileno() | 返回套接字的文件描述符。 |
s.setblocking(flag) | 如果 flag 為 0,則將套接字設(shè)為非阻塞模式,否則將套接字設(shè)為阻塞模式(默認(rèn)值)。非阻塞模式下,如果調(diào)用 recv() 沒有發(fā)現(xiàn)任何數(shù)據(jù),或 send() 調(diào)用無法立即發(fā)送數(shù)據(jù),那么將引起 socket.error 異常。 |
s.makefile() | 創(chuàng)建一個與該套接字相關(guān)連的文件 |
簡單實例
服務(wù)端
我們使用 socket 模塊的?socket?函數(shù)來創(chuàng)建一個 socket 對象。socket 對象可以通過調(diào)用其他函數(shù)來設(shè)置一個 socket 服務(wù)。
現(xiàn)在我們可以通過調(diào)用?bind(hostname, port)?函數(shù)來指定服務(wù)的?port(端口)。
接著,我們調(diào)用 socket 對象的?accept?方法。該方法等待客戶端的連接,并返回?connection?對象,表示已連接到客戶端。
完整代碼如下:
#!/usr/bin/python3
# 文件名:server.py
# 導(dǎo)入 socket、sys 模塊
import socket
import sys
# 創(chuàng)建 socket 對象
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# 獲取本地主機名
host = socket.gethostname()
port = 9999
# 綁定端口
serversocket.bind((host, port))
# 設(shè)置最大連接數(shù),超過后排隊
serversocket.listen(5)
while True:
# 建立客戶端連接
clientsocket,addr = serversocket.accept()
print("連接地址: %s" % str(addr))
msg='歡迎訪問W3Cschool教程!'+ "\r\n"
clientsocket.send(msg.encode('utf-8'))
clientsocket.close()
客戶端
接下來我們寫一個簡單的客戶端實例連接到以上創(chuàng)建的服務(wù)。端口號為 12345。
socket.connect(hosname, port )?方法打開一個 TCP 連接到主機為?hostname?端口為?port?的服務(wù)商。連接后我們就可以從服務(wù)端后期數(shù)據(jù),記住,操作完成后需要關(guān)閉連接。
完整代碼如下:
#!/usr/bin/python3
# 文件名:client.py
# 導(dǎo)入 socket、sys 模塊
import socket
import sys
# 創(chuàng)建 socket 對象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 獲取本地主機名
host = socket.gethostname()
# 設(shè)置端口好
port = 9999
# 連接服務(wù),指定主機和端口
s.connect((host, port))
# 接收小于 1024 字節(jié)的數(shù)據(jù)
msg = s.recv(1024)
s.close()
print (msg.decode('utf-8'))
現(xiàn)在我們打開連個終端,第一個終端執(zhí)行 server.py 文件:
$ python3 server.py
第二個終端執(zhí)行 client.py 文件:
$ python3 client.py
歡迎訪問W3Cschool教程!
這是我們再打開第一個終端,就會看到有以下信息輸出:
連接地址: ('192.168.0.118', 33397)
Python Internet 模塊
以下列出了 Python 網(wǎng)絡(luò)編程的一些重要模塊:文章來源:http://www.zghlxwxcb.cn/news/detail-422113.html
協(xié)議 | 功能用處 | 端口號 | Python 模塊 |
---|---|---|---|
HTTP | 網(wǎng)頁訪問 | 80 | httplib, urllib, xmlrpclib |
NNTP | 閱讀和張貼新聞文章,俗稱為"帖子" | 119 | nntplib |
FTP | 文件傳輸 | 20 | ftplib, urllib |
SMTP | 發(fā)送郵件 | 25 | smtplib |
POP3 | 接收郵件 | 110 | poplib |
IMAP4 | 獲取郵件 | 143 | imaplib |
Telnet | 命令行 | 23 | telnetlib |
Gopher | 信息查找 | 70 | gopherlib, urllib |
更多內(nèi)容可以參閱官網(wǎng)的?Python Socket Library and Modules。文章來源地址http://www.zghlxwxcb.cn/news/detail-422113.html
到了這里,關(guān)于Python入門教程||Python3 MySQL 數(shù)據(jù)庫連接||的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!