sqlite 在 Python 下的再封裝

sqlite 在 Python 下的再封裝

原來一直使用 MongoDB 作為主力數(shù)據(jù)庫,但是單位的電腦是 32 位的機(jī)器,有單一數(shù)據(jù)庫的限制,故一直在尋找替代品。最近發(fā)現(xiàn)原來 sqlite 用起來也不錯(cuò),其 api 簡潔明了。另外,作為一個(gè)文件型數(shù)據(jù)庫, Python 自帶,不需要安裝服務(wù)器軟件,用起來非常方便,并且也不存在安全隱患。

由于本人經(jīng)常寫命令行的軟件,故需要對(duì)系統(tǒng)提供的 api 再進(jìn)一步封裝,更加方便自己的使用。

程序的封裝 sqlite.py

文件頭

import atexit
import sqlite3
from contextlib import contextmanager, closing
from pathlib import Path

_conn = None
_config = {}

db_config

def db_config(database: str, **kw):
    global _config
    kw['database'] = str(database)
    _config = kw

connect

def connect():
    global _conn
    if not _conn:
        _conn = sqlite3.connect(**_config)
        atexit.register(_conn.close)
    return _conn

trans

@contextmanager
def trans():
    try:
        conn = connect()
        yield
        conn.commit()
    except Exception as e:
        conn.rollback()
        raise e

execute

def execute(sql: str, params: list = []):
    return connect().execute(sql, params)

executemany

def executemany(sql: str, params: list = []):
    return connect().executemany(sql, params)

executescript

def executescript(sql: str):
    return connect().executescript(sql)

executefile

def executefile(pkg: str, filename: str):
    '''
    執(zhí)行程序中附帶的資源文件
    pkg         : 所在包的名稱
    filename    : 相關(guān)于包的文件名,包括路徑
    '''
    from pkgutil import get_data
    data = get_data(pkg, filename)
    sql = data.decode('utf8')
    return executescript(sql)

find

def find(sql: str, params: list = [], multi=True):
    '''執(zhí)行sql 語句,并返行多行或一行記錄'''
    cur = execute(sql, params)
    with closing(cur):
        return cur.fetchall()if multi else cur.fetchone()

findone

def findone(sql: str, params: list = []):
    '''執(zhí)行 sql 語句,并返回一行記錄'''
    return find(sql, params, multi=False)

findvalue

def findvalue(sql: str, params: list = []):
    '''執(zhí)行 sql 語句,并返回一個(gè)值 '''
    row = findone(sql, params)
    return row and row[0]

具體使用方法

經(jīng)過封裝后,執(zhí)行數(shù)據(jù)庫指令或查詢時(shí)不用調(diào)用 connect 來連接數(shù)據(jù)庫,先用 db_config來設(shè)置好 connect的參數(shù)就行了。后面的程序在執(zhí)行數(shù)據(jù)庫命令或查詢語句的時(shí)候會(huì)自動(dòng)連接,并在程序退出的時(shí)候自帶關(guān)閉(使用 atexit來實(shí)現(xiàn))。

配置連接參數(shù)

調(diào)用 db_config就行了,其參數(shù)與 sqlite3 庫中的 connect的參數(shù)完全一致。使用方法如下:

db_config(':memory:')

執(zhí)行 sql 語句

共有四條命令可用,其用途如下:

  • execute:沒有參數(shù)或只有一行參數(shù)時(shí)使用
  • executemay:同一條語句多行參數(shù)時(shí)使用
  • executescript:執(zhí)行多條語句,并且無參數(shù)時(shí)使用,一般在定義表或刪除表的時(shí)候使用
  • executefile:執(zhí)行多條語句,并且語句以包數(shù)據(jù)文件的時(shí)候使用

注意: executeexecutemany 需要在 trans 環(huán)境下執(zhí)行,同一個(gè)trans下全部執(zhí)行成功則提交服務(wù)器,執(zhí)行中存在異常則全部回滾。如果不在 trans環(huán)境下執(zhí)行,則連接關(guān)閉后修改的數(shù)據(jù)完全丟失。executescriptexecutefile不需要在 trans環(huán)境下執(zhí)行,會(huì)自動(dòng)提交。故只應(yīng)使用 DDL 語句,而不應(yīng)該插入或修改數(shù)據(jù) 。

具體示例:

建表文件:test.sql

create table if not exists test(
    id  int  primary key,
    name text,
    age  int
);

create table if not exists school(
    userid int primary key,
    class   text
)

執(zhí)行語句示例

db_config(':memory:')

executescript('drop table if exists test;'
             'drop table if exists school;')

executefile('pkg','test.sql')

with trans():
    execute('insert into test values(?,?,?)',[1,'Tom',23])
    executemany('insert into test values(?,?,?)',[
        [2,'Alice',22],
        [3,'John',21]])

查詢語句

執(zhí)行查詢可以使用 find、findonefindvalue三個(gè)命令,其差異如下:

  • find: 執(zhí)行查詢后提取多行數(shù)據(jù)
  • findone: 執(zhí)行查詢后只提取第一行數(shù)據(jù)
  • findvalue:執(zhí)行查詢后只提取第一行數(shù)據(jù)的第一個(gè)值

使用示例:

usercount=findvalue('select count(id) from test')
id,name,age=findone('select * from test where name=?',['tom'])
for id,name,age in find('select * from test'):
    print(id,name,age)

結(jié)語

使用上述方法進(jìn)行封裝后,調(diào)用 sqlite 更加簡潔,避免了數(shù)據(jù)庫連接和關(guān)閉。并且執(zhí)行查詢所產(chǎn)生的cursor均可以自動(dòng)關(guān)閉。

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

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

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,303評(píng)論 2 89
  • 收到了高老師的新作《零售新科學(xué)》,講述數(shù)據(jù)決策如何驅(qū)動(dòng)供應(yīng)鏈變革與績效提升。今天下班后迫不急待地開始翻這本書,看目...
    袁水閱讀 232評(píng)論 0 0
  • 今天學(xué)習(xí)的主要內(nèi)容還是認(rèn)識(shí)函數(shù)的基礎(chǔ)知識(shí),我們說如果想要學(xué)好游泳,首先要培養(yǎng)對(duì)水的熱愛,先要喜歡水,對(duì)水有感覺,而...
    婭_3be4閱讀 265評(píng)論 0 0
  • 第一次踏上北國江南,江南北國的城市,迎面吹來的白雪,記得她也曾經(jīng)說過她是雪季降臨到這個(gè)世界的,也還記得她說她不喜歡...
    苗子愛吃肉閱讀 346評(píng)論 0 0
  • 關(guān)鍵詞:onboarding、習(xí)慣養(yǎng)成、客戶粘性、留存率 我們已經(jīng)提到了如何制作網(wǎng)站的landing page: ...
    強(qiáng)迫癥的幸福指南閱讀 907評(píng)論 0 50

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