10分鍾教你Python+MySQL數據庫操作


欲直接下載代碼文件,關注我們的公眾號哦!查看歷史消息即可!

本文介紹如何利用python來對MySQL數據庫進行操作,本文將主要從以下幾個方面展開介紹:

1.數據庫介紹

2.MySQL數據庫安裝和設置

3.Python操作MySQL

  • 在Python3.X上安裝MySQL驅動

  • 創建數據庫連接

  • 創建數據表

  • 增、改、刪、查

  • 分組、聚合

  • 按批量讀取和處理數據

4.小結

01 數據庫介紹

數據庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫,能直接通過條件快速查詢到指定的數據。隨着信息技術和市場的發展,數據管理不再僅僅是存儲和管理數據,而轉變成用戶所需要的各種數據管理的方式。

目前,數據庫主要有兩種形式,一種是非關系型數據庫,另一種是關系型數據庫。目前,我們用得非常廣泛的一種數據庫類型是關系型數據庫,它可以分為以下幾種:

  • Oracle:
        付費產品,主要是銀行在用(萬一出錯了有Oracle背鍋)

  • DB2:
        付費產品,IBM產品

  • SQL Sever
            付費產品,微軟產品,windows專用

  • PostgreSQL
        免費產品,主要是高校學術上使用

  • MySQL
        大眾,免費,開源

作為手無寸金的大學生,我們應該用哪種數據庫呢?當然是MySQL。一方面是因為MySQL免費,另一方面是因為普及率最高,出了錯,可以很容易找到解決方法。而且,圍繞MySQL有一大堆監控和運維的工具,安裝和使用很方便。所以,本文接下來也會介紹如何用Python來操作MySQL。

02 MySQL安裝和設置

2.1 下載安裝:

  • STEP1****:MySQL官方網站上下載最新的MySQL Installer 8.0.14版本,下載鏈接為:

    https://dev.mysql.com/downloads/installer/

  • STEP2:按照指示操作默認安裝,在安裝時,MySQL會要求我們設置一個本地登陸賬號,賬號名一般命為root,端口為3306,自定義一個password即可。

2.2 MySQL workbench創建用戶與授權

  • STEP1:創建新用戶。以root用戶登錄MySQL workbench,先選擇users and privileges,然后選擇下方的add account去添加用戶。

  • STEP2:我們以創建好的blank為例,創建好后在左邊的表中出現了blank這個用戶。返回MySQL Workbench主頁,新建MySQL Connection,用戶名和密碼為新創建的用戶名和密碼,這個時候,我們就能看到除了root用戶外,還能看到新創建的blank這個user賬戶了。

  • STEP3:創建數據庫和數據表。在root賬戶中新建一個名字為test_s的Schema,然后我們會在左下角的schemas中看到我們新建的schema。對於Schema,在MySQL中,它等同於database,它是數據庫對象的集合,這個集合包括了各種對象,如Tables(表)、Views(視圖)、Sorted Procedures(存儲過程)、Functions等,我們可以選中Table,點擊鼠標右鍵,選擇creat table,即可在該數據庫下創建數據表。創建過程和創建數據庫類似。

  • STEP4****:設置用戶權限:而當我們用blank連接數據庫時,是沒有test_s這個schema的,這個時候我們需要通過root開放權限給blank這個用戶。返回root用戶操作選項卡,選擇users and privileges,選中blank用戶,再選擇schema privileges,點擊add entry;在彈出來的窗口中選擇權限范圍,這里我們選擇指定的test_s給blank這個user,點擊ok;雙擊tets_s,privileges全部授予,點擊select all。

  • STEP5:進入主界面,重新進入blank用戶操作選項卡,我們會在schemas中看到test_s這個schema。blank這個用戶可以對root授權的test_s這個schema中的表進行操作。

至此,我們完成了MySQL中用戶的新建和授權。

03 Python操作MySQL

目前,關於Python操作數據庫主要有以下幾種方法:

  • MySQLdb的使用

MySQLdb是用於Python連接MySQL數據庫的接口,它實現了Python數據庫API規范V2.0,基於MySQL C API上建立的,目前只支持Python2.x。

  • PyMySQL的使用

PyMySQL是Python中用於連接MySQL服務器的一個庫,它支持Python3.x,是一個純Python寫的MySQL客戶端,它的目標是替代MySQLdb。PyMySQL在MIT許可下發布。

  • mysql.connector 的使用

由於 MySQL 服務器以獨立的進程運行,並通過網絡對外服務,所以,需要支持 Python 的 MySQL 驅動來連接到 MySQL 服務器。

目前,有兩個 MySQL 驅動:

  1. mysql-connector-python:是 MySQL 官方的純 Python 驅動

  2. MySQL-python :是封裝了 MySQL C驅動的 Python 驅動

  • SQLAlchemy的使用

是一種ORM(Object-Relational Mapping)框架,將關系數據庫的表結構映射到對象上,隱藏了數據庫操作背后的細節,簡化了數據操作。

3.1 在Python3.X上安裝MySQL驅動

STEP1:由於MySQL官方提供了mysql-connector-python驅動。安裝時,在Anaconda Prompt中輸入:

conda install mysql-connector-python

STEP2:使用以下代碼來測試mysql-connector是否安裝成功:

import mysql.connector

如果沒有產生錯誤,則表明安裝成功。

3.2 創建數據庫連接

這里連接的是我之前創建的blank這個user。如果數據庫已經存在的話,我們可以直接連接;如果數據庫不存在,直接連接則會報錯,這個時候我們就需要創建一個數據庫,創建數據庫可以在MySQL Workbench中創建,也可以在python中使用"CREATE DATABASE"語句,在本實驗中,我們使用已經在MySQL workbench中已經建好的test_s這個數據庫。

import mysql.connector
#連接數據庫
config = {
    'user' : 'blank'        #用戶名
    'password' : 'password' #自己設定的密碼
    'host' : '127.0.0.1'    #ip地址,本地填127.0.0.1,也可以填localhost
    'port' : '3306'         #端口,本地的一般為3306
    'database' : 'test_s'   #數據庫名字,這里選用test_s
}
con = mysq;.connector.connect(**config)

3.3 創建數據表

  • STEP1:當Python 和數據之間的連接建立起來之后,要操作數據庫,就需要讓 Python對數據庫執行SQL語句。創建數據表我們使用"CREATE TABLE"語句,在test_s這個數據庫中創建一個叫做customers的表格,其中包含id、name、address、sex、age、sl這六個columns。Python是通過游標執行SQL語句的,所以,連接建立之后,就要利用連接對象得到游標對象。

cursor():表示游標

execute():是執行語句

  • STEP2****:一般在創建新表的時候,我們還會設置一個主鍵(PRIMARY KEY)來方便進行查詢工作。創建主鍵,我們可以用"INT AUTO_INCREMENT PRIMARY KEY"
# 創建一個表
# buffered = True 不設的話,查詢結果沒有讀完會報錯
# raise errors.InternalError("Unread result found")
mycursor = con.cursor(buffered = True)
mycursor.execute("CREATE TABLE customers(id INT AUTO_INCREMENT PRIMARY KEY, \
                               name VARCHAR(255) , address VARCHAR(255), \
                               7sex VARCHAR(225) , age INT(10) , sl INT(10))")

VARCHAR()表示的是數據類型,定義的是變長字符串;INT()表示整型

  • STEP3:執行語句。執行完后,我們可以回到MySQL workbench,可以看到在test_s下面的customers這個表格,其中Columns為我們創建的id,name,address,sex,age和sl。

  • STEP4:但是,當我們再次執行語句的時候,由於已經創建了"customers"這個表,所以再次執行會報錯,這個時候就需要加一個判斷,判斷這個表是否已經存在於test_s這個數據庫中

    ProgrammingError: Table 'customers' alreadyy exists

  • STEP5****:我們可以用"SHOW TABLES"語句來查看數據表是否已經存在,如果存在就print"table already exists",如果不存在,就print"table does not exist"。

def tableExists(mycursor, name):
    stmt = "SHOW TABLES LIKE '" +name+ "'"
    mycursor.execute(stmt)
    return mycursor.fetchone()
mycursor = con.cursor()
if tableExists(mycursor , 'customers'):
    print("table already exists")
else:
    print("table not exists")

  • STEP6:上面的語句只是為了幫助我們判斷是否有同名表,當我們要新建一個表時,我們可以在這個判斷的基礎上,在創建新表前刪掉數據庫內的同名表,再建新表。刪除我們用的是"DROP TABLE",新建表是"CERATE TABLE"
import mysql.connector  
#連接數據庫  
config = {  
    'user' : 'blank',        
    'password' :'fuying123888',  
    'host' : '127.0.0.1',   
    'port':'3306',           
    'database' : 'test_s'  
}  
con = mysql.connector.connect(**config)  
# 檢查一個表是否存在  
def tableExists(mycursor, name):  
    stmt = "SHOW TABLES LIKE '"+name+"'"  
    mycursor.execute(stmt)  
    return mycursor.fetchone()     
# 刪除一個表(無論它是否已經存在)  
def dropTable(mycursor, name):  
    stmt = "DROP TABLE IF EXISTS "+name  
    mycursor.execute(stmt)  
# buffered=True 不設的話,查詢結果沒有讀完會報錯  
# raise errors.InternalError("Unread result found")  
mycursor = con.cursor(buffered=True)  
# 刪除臨時表  
tableName = 'customers'  
dropTable(mycursor, tableName)  
# 創建一個表       
mycursor.execute("CREATE TABLE customers(id INT AUTO_INCREMENT PRIMARY KEY,\
                               name VARCHAR(255), address VARCHAR(255), \  
                               sex VARCHAR(225), age INT(10), sl INT(10))")

3.4 增、改、刪、查

3.4.1 增

在cutomers表中插入數據用的是"INSERT INTO"語句。

除了用一條條用execute( )插入之外,我們還可以用executemany()的方式批量插入,也就是val中包含的是一個元組列表,包含我們想要插入的數據。

需要注意的事是:如果數據表格有更新,那么必須用到commit()語句,否則在workbench是看不到插入的數據的。


# 往表里插入一些記錄  
sql="INSERT INTO customers(name,address,sex,age,sl) VALUES(%s, %s,%s,%s,%s)"
val = ("John", "Highway 21","M",23,5000)  
mycursor.execute(sql, val)  
val = ("Jenny", "Highway 29","F",30,12500)  
mycursor.execute(sql, val)  
val=[("Tom","ABC 35","M",35,14000),  
     ("Tom1","Highway 29","M",28,6700),  
     ("Lily","Road 11","F",30,8000),  
     ("Martin","Road 24","M",35,14000),  
     ("Sally","Fast 56","M",32,15000)]  
mycursor.executemany(sql, val)  
con.commit()  

執行以上代碼后,回到workbench,,我們可以看到最終的結果為:

image

3.4.2 改

在cutomers表中更改數據用的是"UPDATE"語句。例如,我們將最后一條 “Sally”的名字改成“Tiny”:


# 將Sally改為Tiny  
sql="UPDATE customers SET name='Tiny' WHERE name ='Sally'"  
mycursor.execute(sql)  
con.commit()  

執行代碼,回到workbench我們可以看到結果為:

3.4.3 刪

關於刪,我們在上文提到了刪除表格,用的是“DROP TABLE ”語句,“IF EXISTS”關鍵字是用於判斷表是否存在,只有在存在的情況才刪除當我們要刪除一條數據記錄時候,用到的語句是“DELETE FROM”語句。例如:我們想在customers這個表格當中,刪除name為Tiny的這一條記錄:


#刪除名字為Tiny的記錄  
sql="DELETE FROM  customers WHERE name='Tiny'"  
mycursor.execute(sql)  
con.commit()  

執行代碼,回到workbench我們可以看到結果為:

3.4.4 查

  • 普通查詢

普通查詢數據用的是SELECT語句。例如:我們想查詢customers的所有信息,並且進行打印輸出:

#查詢這里面所有的人:  
sql="SELECT * FROM customers"  
mycursor.execute(sql)  
myresult = mycursor.fetchall()     # fetchall() 獲取所有記錄  
for x in myresult:  
  print(x)  

得到最終結果為:

值得注意的是:fetchall()表示的是獲得所有記錄;fetchone()表示只獲取一條數據;fetchmany(size=3)表示獲取三條記錄;

  • 限定條件查找

為了獲取指定條件下的查找結果,我們可以使用where語句。例如:我們想在查詢customers的所有信息基礎上,輸出年齡大於30歲的消費者的信息:


sql="SELECT * FROM customers WHERE age > 30"  
mycursor.execute(sql)  
myresult = mycursor.fetchall()     # fetchall() 獲取所有記錄  
for x in myresult:  
  print(x)  

最終得到的結果為:

  • 通配符查找

有時候為了進行模糊查詢,可以匹配通配符,通過“LIKE”來進行查找:

百分號 (%):代表零個、一個或多個數字或字符;

下划線 (_):代表一個單一的數字或字符。

例如:查出所有名字中含有t的記錄:


#%代表零個、一個或者多個數字或字符  
#_代表一個單一的數字或者字符  
sql = "SELECT * FROM customers WHERE name LIKE '%t%'"  
mycursor.execute(sql)  
myresult=mycursor.fetchall()  
for x in myresult:  
    print(x)  

執行代碼,我們得到的結果如下:

值得注意的是:但是使用Like查詢時,即使我們在代碼輸入的是“t”,執行過程中也會將含有“T”的記錄同樣輸出,即用LIKE匹配通配符對大小寫不敏感。為了區分大小寫,可以用“GLOB”進行查詢。

  • 排序

查詢結果排序可以使用 ORDER BY 語句,默認的排序方式為升序,如果要設置降序排序,可以設置關鍵字 DESC。例如:我們要按照年齡對customers進行升序排列:

#排序  
#按照年齡排序  
sql = "SELECT * FROM customers ORDER BY age"  
mycursor.execute(sql)  
myresult=mycursor.fetchall()  
for x in myresult:  
    print(x)  

執行代碼,得到的結果為:

n zxx m nb

  • LIMIT

當數據庫數量非常大的時候,為了限制查詢的數據量,可以采用"LIMIT"語句來指定,比如我們希望在customers表中找出工資最高的三個人:


#找出其中工資最高的3個人  
sql = "SELECT * FROM customers ORDER BY sl DESC LIMIT 3"  
mycursor.execute(sql)  
myresult=mycursor.fetchall()  
for x in myresult:  
    print(x)  

執行代碼,得到結果為:

  • 二次篩選

有時候我們在進行一次篩選后,還需要設定一個篩選條件進行二次篩選,我們就可以采用“HAVING”語句。例如:我們希望統計在年齡處於20-30(不包括20歲,但是包括30歲)的人當中,選擇薪資大於5000的消費者:


#二次過濾  
#統計在年齡處於20-30之間的人中,選擇薪資大於5000的人  
sql = "SELECT * FROM customers WHERE age>20 and age<=30 HAVING sl>5000 "  
mycursor.execute(sql)  
myresult=mycursor.fetchall()  
for x in myresult:  
    print(x)  
con.commit()  
con.close()  

執行代碼后,得到的結果如下:

3.5 分組聚合

在數據庫中,分組常用的語句為“GROUP BY”語句,聚合函數,通常是配合分組進行使用,在數據庫中常用的聚合函數為:

  1. COUNT(*):表示計算總行數,括號可以寫*和字段名字

  2. MAX(column):表示求此列的最大值

  3. MIN(column):表示求此列的最小值

  4. SUM(column):表示求此列的和

  5. AVG(column):表示求此列的平均值

  • 從customers表中統計出男女薪資總和

以sex為類別進行GROUP BY 分組,加上WHERE來做條件判斷。

#統計出男女的薪水總數  
sql = "SELECT sex,sum(sl) FROM customers GROUP BY sex"  
mycursor.execute(sql)  
myresult=mycursor.fetchall()  
for x in myresult:  
    print(x)  

最終結果為:

  • 從customers表中,按性別進行分組,統計出年齡在20-30的消費者的薪資,並且按照薪資高低進行排序

# 按照性別進行分組,統計出年齡在20-30歲的消費者的薪資  
sql = "SELECT sex,sum(sl) FROM customers WHERE age>20 and age<=30 GROUP BY sex ORDER BY sl"  
mycursor.execute(sql)  
myresult=mycursor.fetchall()  
for x in myresult:  
    print(x)  

值得注意的是:本例是以sex為類別進行GROUP BY 分組,加上WHERE來做條件判斷,加上ORDER BY 排序,但是GROUP BY 的位置必須要在WHERE 之后,在ORDER BY 之前。

3.6 分批量讀取和處理數據

程序運行的時候,數據都是在內存中的,但是有時候如果數據量太大,內存會裝不下,這個時候我們就需要分批從數據庫去讀取數據,然后再處理,等到處理完了之后,再去讀取。比如:我們要從customers當中分批讀取和處理薪資大於8000的消費者,並將其存入另一張表中。我們的做法是先新建一個表,然后從數據庫當中讀取3個,並且將讀取的這3個進行處理,處理完讀取的這三個后,再去數據庫重新讀取三個,直到數據庫的數據讀完為止。


# 分批讀取並且處理將薪資大於8000的消費者的記錄存到另一張表中  
# 創建一個臨時表   
tmpName = 'cust_tmp'  
dropTable(mycursor, tmpName)    
mycursor.execute("CREATE TABLE cust_tmp(id INT AUTO_INCREMENT PRIMARY KEY,\
                               name VARCHAR(255), address VARCHAR(255), \  
                               sex VARCHAR(225), age INT(10), sl INT(10))")
ins = con.cursor(buffered=True)  
if tableExists(mycursor, tableName):  
    print("process table: %s", tableName)  
    # 查詢表里的記錄  
    sql = "SELECT * FROM customers WHERE address is not null"  
    mycursor.execute(sql)  
    # 每次處理 batchsize 條記錄,直到所有查詢結果處理完  
    batchsize = 3  
    readsize = batchsize  
    while readsize == batchsize:  
        print("before batch")  
        myresult = mycursor.fetchmany(size=batchsize)  
        for x in myresult:  
            if x[5]>8000:  
                ins.execute("INSERT INTO"+tmpName+"(id,name,address,sex,age,sl) VALUES (%s, %s,%s, %s,%s,%s)", x)  
                print(x)  
        readsize = len(myresult)  
else:  
    print("table: does not exists", tableName)  
con.commit()  
con.close()  

我們回到workbench找到這個新建的表格cust_tmp,我們可以發現薪資大於8000的消費者都被記錄上了:

執行代碼,我們可以看到處理的過程如下:

在第一批讀取的三條記錄中,只有兩條是滿足薪資大於8000的要求,第二批讀取的三條記錄中,只有一條滿足薪資大於8000的要求,而在第三批讀取的三條記錄中,沒有任何記錄是滿足薪資大於8000的要求,當沒有記錄可以讀的時候,程序即停止。

值得注意的是:就分批讀取的batchsize而言,當batchsize太大時,會導致內存裝不下,batchsize太小,會導致每次通過網絡連接數據庫會很慢。因此,我們選取batchsize大小的原則是在內存夠用的前提下盡可能的大,在真實的業務場景下,建議每次讀取100以上,當內存夠用的話,也可以增加至幾千上萬條。

04小結

本文介紹了Python+MySQL的基本操作,包括如何安裝Mysql,如何裝驅動,如何創建連接以及對數據庫進行增刪改查、分組聚合以及批量讀取和處理等操作。但是,本文涉及到的只是對單表進行操作,只是數據庫操作的冰山一角;在實際的開發和工作環境中,需要根據實際內容對多表進行操作,這部分請持續關注數據魔術師關於數據庫的后期推文。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM