【Python入門】42.數(shù)據(jù)庫之 使用SQLite

摘要:數(shù)據(jù)庫的簡單介紹;關(guān)系數(shù)據(jù)庫的簡單介紹;SQLite的基本語法介紹


*寫在前面:為了更好的學(xué)習(xí)python,博主記錄下自己的學(xué)習(xí)路程。本學(xué)習(xí)筆記基于廖雪峰的Python教程,如有侵權(quán),請告知刪除。歡迎與博主一起學(xué)習(xí)Pythonヽ( ̄▽ ̄)? *


目錄

數(shù)據(jù)庫
關(guān)系數(shù)據(jù)庫
使用SQLite

數(shù)據(jù)庫

當(dāng)程序運(yùn)行時,數(shù)據(jù)是在內(nèi)存中的,當(dāng)程序終止時,就要把數(shù)據(jù)保存到磁盤。

我們可以把用各式各樣的格式來儲存數(shù)據(jù),如用記事本記錄,以逗號隔開每個數(shù)據(jù);用excel記錄數(shù)據(jù)等等。

但這樣出現(xiàn)各種問題如,讀取數(shù)據(jù)時格式不兼容,難以查詢和閱讀數(shù)據(jù)等等。

數(shù)據(jù)庫就是專門用來管理和儲存數(shù)據(jù)的

關(guān)系數(shù)據(jù)庫

我們現(xiàn)在廣泛使用的是關(guān)系數(shù)據(jù)庫。

什么叫關(guān)系數(shù)據(jù)庫呢?舉個簡單的例子:


數(shù)據(jù)庫1.png

這個表格用于記錄每個事件及對應(yīng)的日期。

注意到,每個年份對應(yīng)多個月份,而每個月份對應(yīng)多個天數(shù),每一天對應(yīng)多個事件。

如果我們查詢2016年的全部數(shù)據(jù),就會把2016年里12個月,每個月對應(yīng)的日及對應(yīng)的每個事件顯示出來。

如果我們查詢2016年1月7日的數(shù)據(jù),就會把a(bǔ)1、a2、a3事件顯示出來。

這種基于表的一對多的關(guān)系就是關(guān)系數(shù)據(jù)庫的基礎(chǔ)。

關(guān)系數(shù)據(jù)庫有很多種,一般我們使用的話是選擇免費(fèi)的開源數(shù)據(jù)庫。

在這里我們將介紹如何通過Python連接使用MySQL。

MySQL的普及率很高,使用起來也很方便。接下來的教程需要用到MySQL,大家可以前往MySQL官方網(wǎng)站下載免費(fèi)的版本。

使用SQLite

在介紹MySQL之前,先介紹SQLite

SQLite是一種嵌入式數(shù)據(jù)庫,由C編寫,體積小,可以集成到各種應(yīng)用中。Python內(nèi)置了SQLite,可以直接使用。

在使用之前介紹一下數(shù)據(jù)庫的基本概念:

是用于存放數(shù)據(jù)的集合。一個數(shù)據(jù)庫包含多個表,如年份表,月份表等,每個表之間通過外鍵關(guān)聯(lián)。

要操作數(shù)據(jù)庫,首先要連接數(shù)據(jù)庫,一個數(shù)據(jù)庫連接稱為一個Connection

連接后,需要打開游標(biāo)Cursor,通過Cursor執(zhí)行SQL語句。

我們試一下通過Python操作SQLite數(shù)據(jù)庫:

在Python交互式命令行下直接操作,

首先導(dǎo)入模塊sqlite3,建立連接,創(chuàng)建游標(biāo):

>>>import sqlite3
>>>conn = sqlite3.connect('test.db')
>>>cursor = conn.cursor()

然后執(zhí)行SQL語句,創(chuàng)建一個user表,并且添加一條數(shù)據(jù):

>>>cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
<sqlite3.Cursor object at 0x0000000002542810>
>>>cursor.execute('insert into user (id, name) values (\'1\', \'Ming\')')
<sqlite3.Cursor object at 0x0000000002542810>

通過cursor對象,執(zhí)行create語句可以創(chuàng)建一個表,執(zhí)行insert語句可以添加數(shù)據(jù),執(zhí)行update語句可以更新數(shù)據(jù),執(zhí)行delete語句可以刪除數(shù)據(jù)。之后我們可以通過rowcount語句返回影響的行數(shù),像這樣:

>>>cursor.rowcount
1

結(jié)果顯示我們剛剛添加了一條數(shù)據(jù)。

我們可以執(zhí)行select語句,然后通過featchall()拿取結(jié)果:

>>> cursor.execute('select * from user where id=?', ('1',))
<sqlite3.Cursor object at 0x0000000002542810>
>>> values = cursor.fetchall()
>>> values
[('1', 'Ming')]

可以看到,返回值是一個list,每一個元素是一個tuple,對應(yīng)每一條數(shù)據(jù)。

這里execute()方法中的?為占位符,當(dāng)需要傳入多個參數(shù)時,就用多個?表示,隨后輸入對應(yīng)的參數(shù),如:

cursor.execute('select * from user where year=? and month=?', ('2018', 'Sept'))

使用完之后記得提交事務(wù),并且把connection和cursor都關(guān)閉,以防數(shù)據(jù)泄露:

>>> cursor.close()
>>> conn.commit()
>>> conn.close()

SQLite支持常見的標(biāo)準(zhǔn)SQL語句以及幾種常見的數(shù)據(jù)類型。具體文檔請參閱SQLite官方網(wǎng)站。

? 【練習(xí)】根據(jù)分?jǐn)?shù)段查找指定的名字
請編寫函數(shù),在Sqlite中根據(jù)分?jǐn)?shù)段查找指定的名字(練習(xí)源自廖雪峰官方)

# -*- coding: utf-8 -*-

import os, sqlite3

db_file = os.path.join(os.path.dirname(__file__), 'test.db')
if os.path.isfile(db_file):
    os.remove(db_file)

# 初始數(shù)據(jù):
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute('create table user(id varchar(20) primary key, name varchar(20), score int)')
cursor.execute(r"insert into user values ('A-001', 'Adam', 95)")
cursor.execute(r"insert into user values ('A-002', 'Bart', 62)")
cursor.execute(r"insert into user values ('A-003', 'Lisa', 78)")
cursor.close()
conn.commit()
conn.close()

# 返回指定分?jǐn)?shù)區(qū)間的名字,并且按分?jǐn)?shù)從小到大排序
def get_score_in(low, high):

    try:
        conn = sqlite3.connect(db_file)
        cursor = conn.cursor()
    # 檢測錯誤
    except sqlite3.DatabaseError as err:
        print(err)
    else:
        # 拿取數(shù)據(jù)并排序
        cursor.execute('select * from user where score >= ? and score <= ? order by score', (low, high))
        data = cursor.fetchall()
        # 返回只包含name的一個list
        return list(map(lambda x:x[1],data))
    finally:
        cursor.close()
        conn.commit()
        conn.close()

# 測試:
assert get_score_in(80, 95) == ['Adam'], get_score_in(80, 95)
assert get_score_in(60, 80) == ['Bart', 'Lisa'], get_score_in(60, 80)
assert get_score_in(60, 100) == ['Bart', 'Lisa', 'Adam'], get_score_in(60, 100)

思路解析:

1.在執(zhí)行select語句時,使用order by score語句實(shí)現(xiàn)分?jǐn)?shù)排序;

2.通過map()函數(shù)實(shí)現(xiàn)只返回數(shù)據(jù)中的名字一項(xiàng);

3.添加try...finally語句保證connection和cursor的關(guān)閉。


以上就是本節(jié)的全部內(nèi)容,感謝你的閱讀。

下一節(jié)內(nèi)容:數(shù)據(jù)庫之 使用MySQL

有任何問題與想法,歡迎評論與吐槽。

和博主一起學(xué)習(xí)Python吧( ̄▽ ̄)~*

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容