10分鐘教你Python+MySQL數據庫操做

欲直接下載代碼文件,關注咱們的公衆號哦!查看歷史消息便可!python

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

1.數據庫介紹sql

2.MySQL數據庫安裝和設置數據庫

3.Python操做MySQLwindows

  • 在Python3.X上安裝MySQL驅動python3.x

  • 建立數據庫鏈接服務器

  • 建立數據表網絡

  • 增、改、刪、查數據結構

  • 分組、聚合app

  • 按批量讀取和處理數據

 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,如何裝驅動,如何建立鏈接以及對數據庫進行增刪改查、分組聚合以及批量讀取和處理等操做。可是,本文涉及到的只是對單表進行操做,只是數據庫操做的冰山一角;在實際的開發和工做環境中,須要根據實際內容對多表進行操做,這部分請持續關注數據魔術師關於數據庫的後期推文。

相關文章
相關標籤/搜索