SQLite數據庫是一款非常小巧的嵌入式開源數據庫軟件,它使用一個文件存儲整個數據庫,優點是使用方便,但是功能相比於其它大型數據庫來說,確實有點差距。由於此次數據庫實踐所需要求不多,所以就使用SQLite來完成。值得一提的是,Python內置SQLite3,所以在Python中使用SQLite,不需要安裝任何東西,直接使用。
一、數據庫(database)簡介
表是數據庫中存放關系數據的集合,一個數據庫里面通常都包含多個表,表和表之間通過外鍵關聯。
因為Python的數據庫模塊有統一的接口標准,所以數據庫操作都有統一的模式。要操作關系數據庫,大致是以下幾步(假設數據庫模塊名稱為db):
- 用db.connect連接數據庫,假設得到的對象為conn
- 如果該數據庫操作不需要返回結果,就直接用conn.execute查詢,根據數據庫事務隔離級別的不同,可能修改數據庫需要conn.commit
- 如果需要返回查詢結果則用conn.cursor創建游標對象cur, 通過cur.execute查詢數據庫,用cur.fetchall/cur.fetchone/cur.fetchmany返回查詢結果。根據數據庫事務隔離級別的不同,可能修改數據庫需要conn.commit
- 關閉cur,conn
二、SQLite使用
(1)SQlite數據庫的導入
1 import sqlite3
(2)創建數據庫/打開數據庫
1 conn = sqlite3.connect("test.db")
在調用connect函數的時候,指定數據庫名稱,如果指定的數據庫存在就直接打開這個數據庫,如果不存在就新創建一個再打開。
(3)數據庫連接對象
打開數據庫時返回的對象conn就是一個數據庫連接對象,有以下幾種基本操作:
1 #創建一個Cursor游標 2 cur = conn.cursor() 3 4 #執行一條SQL語句,創建user表 5 cur.execute('create table user (id varchar(20) primary key, name varchar(20))') 6 7 #執行一條SQL語句,插入一條記錄 8 cur.execute('insert into user (id, name) values (\'1\', \'Michael\')') 9 10 #獲得插入的行數 11 cur.rowcount 12 13 #執行查詢語句 14 cursor.execute('select * from user where id=?', ('1',)) 15 #獲得查詢結果 16 values = cur.fetchall() #如果使用cur.fetchone()則首先返回列表中的第一項,再次使用,則返回第二項,依次下去 17 18 #關閉cur 19 cur.close() 20 21 #提交事務 22 conn.commit() 23 24 #關閉connection連接 25 conn.close()
使用Cursor游標對象執行insert,update,delete語句時,執行結果由rowcount返回影響的行數,就可以拿到執行結果。
使用Cursor游標對象執行select語句時,通過fetchall()可以拿到結果集。結果集是一個list,每個元素都是一個tuple,對應一行記錄。
如果SQL語句帶有參數,那么需要把參數按照位置傳遞給execute()方法,有幾個?占位符就必須對應幾個參數。另外一種方法是使用字符串格式化format()方法。
以上為SQLite數據庫的常用的基本操作,具體用法請參閱SQLite的官方網站。(SQLite數據庫菜鳥教程)
三、SQLite數據庫實踐
(1)將上次爬取得到的2017中國最好大學排名.csv文件以db格式文件寫入數據庫
1 #!D:/Python/Python.exe 2 # -*- coding: utf-8 -*- 3 import sqlite3 as sql 4 5 #獲取csv文件的數據 6 def GetData(Csv_Path): 7 with open(Csv_Path, "r", encoding="utf-8") as f: 8 lines = f.readlines() 9 Data = lines[1:] 10 Headers = lines[0].replace('\n', '') 11 Headers = Headers.split(',') 12 return Data, tuple(Headers) 13 14 #創建數據庫 15 def CreateDB(DB_Path, Headers, Tab_name): 16 try: 17 conn = sql.connect(DB_Path) 18 cur = conn.cursor() 19 cur.execute('''CREATE TABLE {0} {1}'''.format(Tab_name, Headers)) 20 print("Table created successfully") 21 return conn, cur 22 except: 23 print("Created failed") 24 25 #將數據導入數據庫 26 def Import(Csv_Path, DB_Path, Tab_name): 27 Data, Headers = GetData(Csv_Path) 28 Conn, Cur = CreateDB(DB_Path, Headers, Tab_name) 29 #為了之后的排序工作, 以下進行了數據處理 30 for row in Data: 31 row = row.replace('無', '0') 32 row = row.replace('\n', '') 33 row = tuple(row.split(',')) 34 Cur.execute("INSERT INTO {0} VALUES {1}".format(Tab_name, row)) 35 print("Data import successful") 36 Conn.commit() #提交事務 37 Cur.close() #關閉游標 38 Conn.close() #關閉數據庫連接 39 40 if __name__ == "__main__": 41 Csv_Path = input("請輸入需要導入的csv文件的路徑或名稱:") 42 DB_Name = input("請輸入數據庫的名稱:") 43 Tab_name = input("請輸入數據庫的表名稱:") 44 Import(Csv_Path, DB_Name, Tab_name) 46
將結果用SQLite Studio呈現:


SQLite Studio是一款 Sqlite數據庫可視化工具,使用非常簡單,想要了解的話這里給一個我參考的教程。(SQLite Studio使用教程)
(2)查詢學校的數據
1 import sqlite3 as sql 2 Conn = sql.connect("db2019310143115.db") 3 Cur = Conn.execute("SELECT * from Rank where 學校名稱 = ?", ('廣東技術師范學院',)) #這句代碼是產生一個指定位置的cursor游標 4 row = Cur.fetchone() 5 print(row) 6 Cur.close() 7 Conn.close()
這里只是單純執行一句sql語句實現查詢,並未整合在上面的代碼。值得一提的是connection.execute()與cursor.execute()不相同,前者是產生一個游標,后者是直接操作游標。
結果為:

(3)按照要求查詢並顯示廣東省的學校的排名和成果轉化
1 1 import sqlite3 as sql 2 2 Conn = sql.connect("db2019310143115.db") 3 3 Cur = Conn.execute("SELECT 學校名稱, 成果轉化(技術轉讓收入·千元) FROM Rank order by 成果轉化(技術轉讓收入·千元) desc") #執行sql的order by語句進行排序, desc為倒序, 默認為順序 4 4 for i in Cur.fetchall(): 5 5 print(i) 6 6 Cur.close() 7 7 Conn.close()
一部分結果為(左邊是學校名稱,右邊是成果轉化的數據):

(4)將廣東省(或全國)的學校的排名和數據存為一個新表,並且使用一個算法,綜合每個因素進行總排名
由於這一要求並未完成,我僅把上面的功能整合在一起,給出代碼:
1 #!D:/Python/Python.exe 2 # -*- coding: utf-8 -*- 3 import sqlite3 as sql 4 5 #獲取csv文件的數據 6 def GetData(): 7 Csv_Path = input("請輸入csv文件的路徑或名稱:") 8 with open(Csv_Path, "r", encoding="utf-8") as f: 9 lines = f.readlines() 10 Data = lines[1:] 11 Headers = lines[0].replace('\n', '') 12 Headers = Headers.split(',') 13 return Data, tuple(Headers) 14 15 #創建新表 16 def CreateDB(Headers, Cur): 17 Tab_name = input("請輸入表名稱:") 18 try: 19 Cur.execute('''CREATE TABLE {0} {1}'''.format(Tab_name, Headers)) 20 print("Table created successfully.") 21 except: 22 print("Creation failed.") 23 24 #將數據導入數據庫 25 def Import(Data, Cur): 26 Tab_name = input("請輸入表的名稱: ") 27 #為了之后的排序工作, 以下進行了數據處理 28 for row in Data: 29 row = row.replace('無', '0') 30 row = row.replace('\n', '') 31 row = row.split(',') 32 for i in range(len(row)): 33 try: 34 row[i] = eval(row[i]) 35 except: 36 continue 37 Cur.execute("INSERT INTO {} VALUES {}".format(Tab_name, tuple(row))) #執行sql語句, 寫入數據 38 print("Data imported successfully.") 39 40 #查詢數據 41 def Search(Headers, Cur): 42 Tab_name = input("請輸入表的名稱: ") 43 School = input("請輸入想要查找的學校: ") 44 Cur.execute("SELECT * FROM {} WHERE 學校名稱 = ?".format(Tab_name), (School,)) 45 Info = Cur.fetchone() 46 for i in range(len(Headers)): 47 print("{}: {}".format(Headers[i], Info[i])) 48 49 #排序 50 def Sort(Cur): 51 Tab_name = input("請輸入表的名稱: ") 52 Col = input("請輸入想要按照哪列進行排序(默認倒序): ") 53 Cur.execute("SELECT 學校名稱, 成果轉化(技術轉讓收入·千元) FROM {} order by {} desc".format(Tab_name, Col)) 54 for i in Cur.fetchall(): 55 print(i) 56 57 #數據庫功能 58 def Function(Data, Headers): 59 DB_Path = input("請輸入數據庫的路徑或名稱:") 60 try: 61 Conn = sql.connect(DB_Path) 62 Cur = Conn.cursor() 63 print("Connect completed.") 64 except: 65 print("Connection fail.") 66 else: 67 while True: 68 Choi = input("請選擇你想要使用的功能(1、創建新表 2、插入數據 3、查詢 4、排序 0、退出):") 69 if Choi == "0": 70 Cur.close() 71 Conn.close() 72 print("Database closed successfully.") 73 break 74 elif Choi == "1": 75 CreateDB(Headers, Cur) 76 elif Choi == "2": 77 Import(Data, Cur) 78 Conn.commit() 79 elif Choi == "3": 80 Search(Headers, Cur) 81 elif Choi == "4": 82 Sort(Cur) 83 else: 84 print("Input Error!") 85 86 if __name__ == "__main__": 87 Data, Headers = GetData() 88 Function(Data, Headers)
未完待續...
