最全總結 | 聊聊 Python 數據處理全家桶(Sqlite篇)

image

1. 前言

上篇文章 聊到 Python 處理 Mysql 數據庫最常見的兩種方式,本篇文章繼續(xù)說另外一種比較常用的數據庫:Sqlite

Sqlite 是一種 嵌入式數據庫,數據庫就是一個文件,體積很小,底層由 C 語言編寫,經常被集成到移動應用程序中

事實上,Python 內置了 sqlite3 模塊,不需要安裝任何依賴,就可以直接操作 Sqlite 數據庫

2. 準備

和 Python 操作 Mysql 類似,操作 Sqlite 主要包含下面 2 種方式:

  • sqlite3 + 原生 SQL

  • SQLAlchemy + ORM

3. sqlite3 + 原生 SQL

由于 Python 內置了 sqlite3 模塊,這里直接導入就可以使用了

# 導入內置模塊sqlite3
import sqlite3

首先,我們使用 sqlite3 的 connnect() 方法創(chuàng)建一個數據庫連接對象,如果數據庫不存在,就自動在對應目錄下新建一個數據庫文件

# 創(chuàng)建數據庫連接對象,如果數據庫不存在,就自動新建一個數據庫文件
# 還可以指定其他參數,包含:超時時間
 self.conn = sqlite3.connect(self.path_db)

然后,通過數據庫連接對象獲取一個操作數據庫的 游標實例

# 獲取操作數據庫的游標對象
self.cursor = self.conn.cursor()

接著,使用數據庫連接對象執(zhí)行創(chuàng)建表的 SQL 語句,在數據庫內新建一張表

# 創(chuàng)建表
SQL_CREATE_TABLE = '''CREATE TABLE IF NOT EXISTS PEOPLE
       (ID INT PRIMARY KEY     NOT NULL,
       NAME           TEXT    NOT NULL,
       AGE            INT     NOT NULL);'''

def create_db_table(self):
    """
    初始化表
    :return:
    """
    self.conn.execute(SQL_CREATE_TABLE)

接下來,我們通過增刪改查來操作數據表

1、新增

同樣以新增單條數據和多條數據為例

對于單條數據的插入,只需要編寫一條插入的 SQL 語句,然后作為參數執(zhí)行上面數據庫連接對象的 execute(sql) 方法,最后使用數據庫連接對象的 commit() 方法將數據提交到數據庫中

# 插入一條數據
SQL_INSERT_ONE_DATA = "INSERT INTO PEOPLE(id,name,age) VALUES(3,'xag',23);"

def insert_one(self):
    """新增一條數據"""
    try:
        self.conn.execute(SQL_INSERT_ONE_DATA)
        # 必須要提交,才能正確執(zhí)行
        self.conn.commit()
    except Exception as e:
        self.conn.rollback()
        print('插入一條記錄失敗,回滾~')

需要注意的是,插入操作經常會因為主鍵原因導致新增異常,所以需要捕獲異常,執(zhí)行回滾操作

使用數據庫連接對象的 executemany() 方法,傳入插入的 SQL 語句及 位置變量列表,可以實現一次插入多條數據

# 插入多條數據(3個變量,包含:id、name、value)
SQL_INSERT_MANY_DATA = 'INSERT INTO PEOPLE (id,name,age) VALUES(?,?,?);'

# 待插入的數據
self.data = [(4, '張三', 11), (5, '李四', 12), (6, '王五', 13)]

def insert_many(self, data):
    """新增多條數據"""
    try:
        self.conn.executemany(SQL_INSERT_MANY_DATA, data)
        self.conn.commit()
    except Exception as e:
        self.conn.rollback()
        print('插入多條記錄失敗,回滾~')

2、查詢

查詢分為 2 步,分別是:

  • 通過游標對象執(zhí)行查詢的 SQL 語句

  • 調用游標對象的方法獲取查詢結果

比如:

要獲取所有數據,可以使用游標對象的 fetchall() 方法

要獲取第一條滿足條件的數據,可以使用 fetchone() 方法

另外,fetchmany(num) 可以查詢固定數量的數據

# 查詢的SQL語句
SQL_QUERY_ONE_DATA = "SELECT * FROM PEOPLE WHERE id={}"

def query_one(self, id):
    """
    查詢一條數據
    :param id:
    :return:
    """
    self.cursor.execute(SQL_QUERY_ONE_DATA.format(id))

    # fetchone():查詢第一條數據
    # fetchall():查詢所有數據
    # fetchmany(1):查詢固定的數量的數據
    result = self.cursor.fetchall()
    print(type(result))
    print(result)

3、更新

和 新增操作 類似,更新操作也是通過數據庫連接對象去執(zhí)行更新的 SQL 語句,最后執(zhí)行提交操作,將數據真實更新到數據表中

以更新某一條記錄為例

# 更新數據
SQL_UPDATE_ONE_DATA = "UPDATE PEOPLE SET NAME = '{}',AGE={} where id = {}"

def update_one(self, id, name, age):
    """
    修改一條記錄
    :param id:
    :param name:
    :param age:
    :return:
    """
    sql_update = SQL_UPDATE_ONE_DATA.format(name, age, id)
    print(sql_update)
    self.conn.execute(sql_update)
    self.conn.commit()

4、刪除

刪除操作同查詢、新增操作類似,只需要執(zhí)行刪除的 SQL 語句即可

以刪除某一條記錄為例

# 刪除數據
SQL_DEL_ONE_DATA = "DELETE FROM PEOPLE where id ={}"

def del_one(self, id):
    """通過id去刪除一條數據"""
    sql_del = SQL_DEL_ONE_DATA.format(id)
    self.conn.execute(sql_del)
    self.conn.commit()

最后,我們同樣需要將游標對象和數據庫連接對象,資源釋放

def teardown(self):
    # 關閉游標和數據庫連接,避免資源浪費
    self.cursor.close()
    self.conn.close()

4. SQLAlchemy + ORM

使用 SQLAlchemy 操作 sqlite 數據庫同樣先需要安裝依賴庫

# 安裝依賴包
pip3 install sqlalchemy

通過內置方法 declarative_base() 創(chuàng)建一個基礎類 Base

然后,自定義一個 Base 類的子類,內部通過定義靜態(tài)變量指定表名、表的字段

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base

# 基礎類
Base = declarative_base()


# 自定義的表
class People(Base):
    # 表名
    __tablename__ = 'people'

    # 定義字段
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

    def __repr__(self):
        """
        便于打印結果
        :return:
        """
        return "<People(id:{},name:{},age:{})".format(self.id, self.name, self.age)

接著,通過 SQLAlchemy 的 create_engine(sqlite數據庫路徑) 方法中創(chuàng)建數據庫連接對象

格式為:sqlite:///數據庫相對路徑

# 創(chuàng)建數據庫連接
engine = create_engine('sqlite:///./xh.db', echo=True)

最后,通過數據庫引擎在數據庫中創(chuàng)建表結構,并實例化一個 數據庫會話對象

PS:數據庫會話對象內置的方法非常方便我們進行增刪改查操作

# 創(chuàng)建表結構
# checkfirst:判斷表是否存在,如果存在,就不重復創(chuàng)建
Base.metadata.create_all(engine, checkfirst=True)

# 實例化會話
self.session = sessionmaker(bind=engine)()

這樣所有的準備工作已經完成,接下來可以進行增刪改查操作了

1、新增

新增操作同樣以新增一條和多條記錄為例,它們分別對應會話對象的 add()、add_all() 方法

對于一條記錄的新增操作,只需要實例化一個 People 對象,執(zhí)行上面的會話對象的 add(instance) 和 commit() 兩個方法,即可以將數據插入到數據表中

def add_one_data(self):
    """新增一條數據"""
    # 創(chuàng)建一個表的實例對象
    people = People(name='xag1', age=24)
    self.session.add(people)

    # 必須提交,才能更新到數據庫中
    self.session.commit()

如果需要一次插入多條數據,只需要調用 add_all(列表數據) 即可

def add_datas(self, data):
    """
    新增多條數據
    :return:
    """
    self.session.add_all(data)
    self.session.commit()

2、查詢

查詢數據表的操作對應會話對象的 query() 方法

同時,還可以結合 all()、first()、filter_by(限制條件) 級聯(lián)方法限制要查詢的數據

以查詢所有記錄和根據 id 查詢一條記錄為例

def query_one_data(self, id):
    """
    通過id去查詢一條數據
    :param id:
    :return:
    """
    # 通過id去查詢數據,取第一條
    people = self.session.query(People).filter_by(id=id).first()
    print(people)
    print(type(people))

def query_all(self):
    """
    查詢所有數據
    :return:
    """
    peoples = self.session.query(People).all()
    print(peoples)
    print(type(peoples))

3、更新

更新操作一般做法是:

  • query 查詢出待更新的對象

  • 直接更新對象中的數據

  • 使用會話對象提交修改,完成更新操作

def update1(self, id, name, age):
    """
    更新記錄
    :param id:
    :param name:
    :param age:
    :return:
    """
    # 更新步驟:先查詢、修改數據、然后確認修改
    people_temp = self.session.query(People).filter_by(id=id).first()

    # 修改數據
    people_temp.name = name
    people_temp.age = age

    # 確認提交修改
    self.session.commit()

需要指出的是,這里也可以使用內置方法 update() ,對上面的更新操作進行簡寫

def update2(self, id, name, age):
    """
    更新記錄方法2
    :param id:
    :param name:
    :param age:
    :return:
    """
    self.session.query(People).filter_by(id=id).update({People.name: name, People.age: age})
    self.session.commit()

4、刪除

和更新操作一樣,刪除操作也有兩種實現方式

第一種方式的思路是,先查詢,后刪除,最后提交會話完成刪除操作

以按照 id 刪除某一條記錄為例:

def del_one_data1(self, id):
    """
    刪除一條數據方法1
    :param id:
    :return:
    """
    people_temp = self.session.query(People).filter_by(id=id).first()

    # 判斷是否為空
    if people_temp is not None:
        self.session.delete(people_temp)
        self.session.commit()
    else:
        print('此條記錄不存在,刪除失??!')

需要注意的是,查詢的結果必須判斷是否為空,否則直接執(zhí)行刪除操作,可以會拋出異常

另外一種方式是,直接使用級聯(lián)函數將上面的刪除操作進行簡寫

def del_one_data2(self, id):
    """
    刪除一條數據方法2
    :param id:
    :return:
    """
    try:
        self.session.query(People).filter_by(id=id).first().delete()
    except Exception as e:
        print('刪除失敗')

同樣,這種刪除操作需要捕獲異常,避免查詢的結果為空的情況

最后,完成所有操作之后,我們需要結束會話、銷毀數據庫引擎

def teardown(self):
    """
    釋放資源
    :return:
    """
    # 結束會話
    self.session.close()

    # 銷毀引擎
    self.engine.dispose()

5.最后

本篇文章通過一張表的增刪改查,詳細講解了 Python 操作 sqlite 的兩種使用方式

我已經將文中全部源碼上傳到后臺,關注公眾號「 AirPython 」后回復「 dball 」即可獲得全部源碼

如果你覺得文章還不錯,請大家 點贊、分享、留言下,因為這將是我持續(xù)輸出更多優(yōu)質文章的最強動力!

推薦閱讀

聊聊 Python 數據處理全家桶(Mysql 篇)

Python 如何使用 HttpRunner 做接口自動化測試

Python 自動化,Helium 憑什么取代 Selenium?

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

友情鏈接更多精彩內容