sqlite3 — SQLite 資料庫的 DB-API 2.0 介面

原始碼: Lib/sqlite3/

SQLite 是一個 C 庫,提供了一個輕量級的基於磁碟的資料庫,它不需要單獨的伺服器程序,並且允許使用 SQL 查詢語言的非標準變體來訪問資料庫。一些應用程式可以使用 SQLite 進行內部資料儲存。也可以使用 SQLite 原型化一個應用程式,然後將程式碼移植到更大的資料庫,例如 PostgreSQL 或 Oracle。

sqlite3 模組由 Gerhard Häring 編寫。它提供了一個符合 PEP 249 描述的 DB-API 2.0 規範的 SQL 介面,並且需要 SQLite 3.15.2 或更高版本。

本文件包含四個主要部分

  • 教程 教導如何使用 sqlite3 模組。

  • 參考 描述了此模組定義的類和函式。

  • 操作指南 詳細說明了如何處理特定任務。

  • 說明 提供了有關事務控制的深入背景。

另請參閱

https://www.sqlite.org

SQLite 網頁;該文件描述了受支援的 SQL 方言的語法和可用資料型別。

https://w3schools.tw/sql/

用於學習 SQL 語法的教程、參考和示例。

PEP 249 - 資料庫 API 規範 2.0

由 Marc-André Lemburg 編寫的 PEP。

教程

在本教程中,您將使用基本的 sqlite3 功能建立一個 Monty Python 電影的資料庫。它假設對資料庫概念有基本的瞭解,包括遊標事務

首先,我們需要建立一個新的資料庫並開啟資料庫連線,以允許 sqlite3 使用它。呼叫 sqlite3.connect() 以建立與當前工作目錄中的資料庫 tutorial.db 的連線,如果它不存在,則隱式建立它

import sqlite3
con = sqlite3.connect("tutorial.db")

返回的 Connection 物件 con 表示與磁碟資料庫的連線。

為了執行 SQL 語句並從 SQL 查詢中獲取結果,我們需要使用資料庫遊標。呼叫 con.cursor() 以建立 Cursor

cur = con.cursor()

現在我們已經有了資料庫連線和遊標,我們可以建立一個數據庫表 movie,其中包含標題、發行年份和評論分數的列。為簡單起見,我們可以在表宣告中僅使用列名 – 感謝 SQLite 的靈活型別功能,指定資料型別是可選的。透過呼叫 cur.execute(...) 來執行 CREATE TABLE 語句

cur.execute("CREATE TABLE movie(title, year, score)")

我們可以透過查詢 SQLite 內建的 sqlite_master 表來驗證是否已建立新表,該表現在應包含 movie 表定義的條目(有關詳細資訊,請參閱 模式表)。透過呼叫 cur.execute(...) 執行該查詢,將結果分配給 res,並呼叫 res.fetchone() 以獲取結果行

>>> res = cur.execute("SELECT name FROM sqlite_master")
>>> res.fetchone()
('movie',)

我們可以看到該表已建立,因為查詢返回一個包含表名的 tuple。如果我們查詢 sqlite_master 中不存在的表 spamres.fetchone() 將返回 None

>>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'")
>>> res.fetchone() is None
True

現在,透過執行 INSERT 語句來新增兩條以 SQL 字面量形式提供的資料行,再次透過呼叫 cur.execute(...)

cur.execute("""
    INSERT INTO movie VALUES
        ('Monty Python and the Holy Grail', 1975, 8.2),
        ('And Now for Something Completely Different', 1971, 7.5)
""")

INSERT 語句會隱式地開啟一個事務,在更改儲存到資料庫之前,需要提交該事務(詳細資訊請參閱 事務控制)。在連線物件上呼叫 con.commit() 來提交事務。

con.commit()

我們可以透過執行 SELECT 查詢來驗證資料是否正確插入。使用我們現在熟悉的 cur.execute(...) 將結果賦值給 res,然後呼叫 res.fetchall() 返回所有結果行。

>>> res = cur.execute("SELECT score FROM movie")
>>> res.fetchall()
[(8.2,), (7.5,)]

結果是一個包含兩個 tuplelist,每行一個,每個 tuple 包含該行的 score 值。

現在,透過呼叫 cur.executemany(...) 插入另外三行。

data = [
    ("Monty Python Live at the Hollywood Bowl", 1982, 7.9),
    ("Monty Python's The Meaning of Life", 1983, 7.5),
    ("Monty Python's Life of Brian", 1979, 8.0),
]
cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data)
con.commit()  # Remember to commit the transaction after executing INSERT.

請注意,使用 ? 佔位符將 data 繫結到查詢。始終使用佔位符而不是 字串格式化 來將 Python 值繫結到 SQL 語句,以避免 SQL 注入攻擊(有關詳細資訊,請參閱 如何使用佔位符在 SQL 查詢中繫結值)。

我們可以透過執行 SELECT 查詢來驗證是否插入了新行,這次迭代查詢結果。

>>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"):
...     print(row)
(1971, 'And Now for Something Completely Different')
(1975, 'Monty Python and the Holy Grail')
(1979, "Monty Python's Life of Brian")
(1982, 'Monty Python Live at the Hollywood Bowl')
(1983, "Monty Python's The Meaning of Life")

每一行都是一個包含兩個元素的 tuple,格式為 (year, title),與查詢中選擇的列匹配。

最後,透過呼叫 con.close() 關閉現有連線,開啟一個新連線,建立一個新的遊標,然後查詢資料庫,來驗證資料庫是否已寫入磁碟。

>>> con.close()
>>> new_con = sqlite3.connect("tutorial.db")
>>> new_cur = new_con.cursor()
>>> res = new_cur.execute("SELECT title, year FROM movie ORDER BY score DESC")
>>> title, year = res.fetchone()
>>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}')
The highest scoring Monty Python movie is 'Monty Python and the Holy Grail', released in 1975
>>> new_con.close()

你現在已經使用 sqlite3 模組建立了一個 SQLite 資料庫,並以多種方式向其中插入資料和檢索值。

參考

模組函式

sqlite3.connect(database, timeout=5.0, detect_types=0, isolation_level='DEFERRED', check_same_thread=True, factory=sqlite3.Connection, cached_statements=128, uri=False, *, autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL)

開啟與 SQLite 資料庫的連線。

引數:
  • database (類路徑物件) – 要開啟的資料庫檔案的路徑。你可以傳遞 ":memory:" 來建立一個 僅存在於記憶體中的 SQLite 資料庫,並開啟一個連線到它的連線。

  • timeout (float) – 當表被鎖定時,連線在引發 OperationalError 之前應等待的秒數。如果另一個連線開啟一個事務來修改一個表,該表將被鎖定,直到事務被提交。預設為五秒。

  • detect_types (int) – 控制是否以及如何查詢 SQLite 本身不支援 的資料型別,並使用透過 register_converter() 註冊的轉換器將其轉換為 Python 型別。將其設定為 PARSE_DECLTYPESPARSE_COLNAMES 的任意組合(使用 | 按位或)來啟用此功能。如果同時設定了兩個標誌,列名將優先於宣告的型別。即使設定了 *detect_types* 引數,也無法檢測生成欄位(例如 max(data))的型別;將返回 str。預設情況下(0),停用型別檢測。

  • isolation_level (str | None) – 控制傳統的事務處理行為。有關詳細資訊,請參閱 Connection.isolation_level透過 isolation_level 屬性進行事務控制。可以是 "DEFERRED"(預設)、"EXCLUSIVE""IMMEDIATE";或 None 來停用隱式開啟事務。除非 Connection.autocommit 設定為 LEGACY_TRANSACTION_CONTROL (預設值),否則無效。

  • check_same_thread (bool) – 如果為 True(預設),如果資料庫連線被建立它的執行緒以外的執行緒使用,則會引發 ProgrammingError。如果為 False,則可以在多個執行緒中訪問連線;寫入操作可能需要由使用者序列化以避免資料損壞。有關詳細資訊,請參閱 threadsafety

  • factory (Connection) – 如果不是預設的 Connection 類,則可以使用 Connection 的自定義子類來建立連線。

  • cached_statements (int) – sqlite3 應該為此連線內部快取的語句數,以避免解析開銷。預設情況下為 128 個語句。

  • uri (bool) – 如果設定為 True,則 database 被解釋為帶有檔案路徑和可選查詢字串的 URI。scheme 部分*必須*是 "file:",並且路徑可以是相對的或絕對的。查詢字串允許將引數傳遞給 SQLite,從而啟用各種 如何使用 SQLite URI

  • autocommit ( bool ) – 控制 PEP 249 事務處理行為。 詳情請參閱 Connection.autocommit透過 autocommit 屬性進行事務控制autocommit 目前預設為 LEGACY_TRANSACTION_CONTROL。 在未來的 Python 版本中,預設值將更改為 False

返回型別:

Connection

引發一個 審計事件 sqlite3.connect,引數為 database

引發一個 審計事件 sqlite3.connect/handle,引數為 connection_handle

3.4 版本更改: 添加了 uri 引數。

3.7 版本更改: database 現在也可以是 path-like object,而不僅限於字串。

3.10 版本更改: 添加了 sqlite3.connect/handle 審計事件。

3.12 版本更改: 添加了 autocommit 引數。

3.13 版本更改: 引數 timeoutdetect_typesisolation_levelcheck_same_threadfactorycached_statementsuri 的位置用法已棄用。 它們將在 Python 3.15 中變為僅限關鍵字的引數。

sqlite3.complete_statement(statement)

如果字串 statement 似乎包含一個或多個完整的 SQL 語句,則返回 True。 除了檢查是否存在未閉合的字串文字,以及語句是否以分號結尾外,不會執行任何語法驗證或解析。

例如

>>> sqlite3.complete_statement("SELECT foo FROM bar;")
True
>>> sqlite3.complete_statement("SELECT foo")
False

此函式在命令列輸入期間可能很有用,以確定輸入的文字是否構成完整的 SQL 語句,或者在呼叫 execute() 之前是否需要額外的輸入。

有關實際使用情況,請參閱 Lib/sqlite3/__main__.py 中的 runsource()

sqlite3.enable_callback_tracebacks(flag, /)

啟用或停用回調回溯。 預設情況下,您不會在使用者定義的函式、聚合、轉換器、授權回撥等中獲得任何回溯。 如果您想除錯它們,可以使用設定為 Trueflag 呼叫此函式。 之後,您將從 sys.stderr 上的回撥中獲得回溯。 使用 False 再次停用該功能。

注意

使用者定義函式回撥中的錯誤會作為無法引發的異常記錄。 使用 unraisable hook handler 來內省失敗的回撥。

sqlite3.register_adapter(type, adapter, /)

註冊一個 adapter 可呼叫物件,以將 Python 型別 type 轉換為 SQLite 型別。 呼叫介面卡時,將使用型別為 type 的 Python 物件作為其唯一引數,並且必須返回 SQLite 本機理解的型別 的值。

sqlite3.register_converter(typename, converter, /)

註冊 converter 可呼叫物件,將型別為 typename 的 SQLite 物件轉換為特定型別的 Python 物件。 將為所有型別為 typename 的 SQLite 值呼叫轉換器; 它會傳遞一個 bytes 物件,並應返回所需 Python 型別的物件。 有關型別檢測如何工作的資訊,請查閱 connect() 的引數 detect_types

注意:typename 和查詢中型別的名稱匹配時不區分大小寫。

模組常量

sqlite3.LEGACY_TRANSACTION_CONTROL

autocommit 設定為此常量可選擇舊樣式(Python 3.12 之前的版本)事務控制行為。 詳情請參閱 透過 isolation_level 屬性進行事務控制

sqlite3.PARSE_COLNAMES

將此標誌值傳遞給 connect()detect_types 引數,以透過使用從查詢列名稱解析的型別名稱作為轉換器字典鍵來查詢轉換器函式。 型別名稱必須用方括號 ( [] ) 括起來。

SELECT p as "p [point]" FROM test;  ! will look up converter "point"

此標誌可以與 PARSE_DECLTYPES 結合使用,方法是使用 | (按位或)運算子。

sqlite3.PARSE_DECLTYPES

將此標誌值傳遞給 connect()detect_types 引數,以使用每個列的宣告型別查詢轉換器函式。 這些型別是在建立資料庫表時宣告的。 sqlite3 將使用宣告型別的第一個單詞作為轉換器字典鍵來查詢轉換器函式。 例如

CREATE TABLE test(
   i integer primary key,  ! will look up a converter named "integer"
   p point,                ! will look up a converter named "point"
   n number(10)            ! will look up a converter named "number"
 )

此標誌可以與 PARSE_COLNAMES 結合使用,方法是使用 | (按位或)運算子。

sqlite3.SQLITE_OK
sqlite3.SQLITE_DENY
sqlite3.SQLITE_IGNORE

這些標誌應由傳遞給 Connection.set_authorizer()authorizer_callback 可呼叫物件 返回,以指示是否

  • 允許訪問 ( SQLITE_OK ),

  • 應該中止 SQL 語句並顯示錯誤 ( SQLITE_DENY )

  • 應將該列視為 NULL 值 ( SQLITE_IGNORE )

sqlite3.apilevel

字串常量,表示支援的 DB-API 級別。 DB-API 要求。 硬編碼為 "2.0"

sqlite3.paramstyle

字串常量,表示 sqlite3 模組期望的引數標記格式型別。 DB-API 要求。 硬編碼為 "qmark"

注意

還支援 named DB-API 引數樣式。

sqlite3.sqlite_version

執行時 SQLite 庫的版本號,為 字串

sqlite3.sqlite_version_info

執行時 SQLite 庫的版本號,以 tuple 形式的 整數 表示。

sqlite3.threadsafety

DB-API 2.0 所需的整數常量,表示 sqlite3 模組支援的執行緒安全級別。此屬性根據底層 SQLite 庫編譯時使用的預設執行緒模式設定。SQLite 執行緒模式為:

  1. 單執行緒:在此模式下,所有互斥鎖都被停用,SQLite 在多個執行緒中同時使用是不安全的。

  2. 多執行緒:在此模式下,只要不在兩個或多個執行緒中同時使用單個數據庫連線,SQLite 就可以安全地被多個執行緒使用。

  3. 序列化:在序列化模式下,SQLite 可以安全地被多個執行緒使用,沒有任何限制。

從 SQLite 執行緒模式到 DB-API 2.0 執行緒安全級別的對映如下:

SQLite 執行緒模式

threadsafety

SQLITE_THREADSAFE

DB-API 2.0 含義

單執行緒

0

0

執行緒可能不共享模組

多執行緒

1

2

執行緒可以共享模組,但不能共享連線

序列化

3

1

執行緒可以共享模組、連線和遊標

在 3.11 版本中更改: 動態設定threadsafety,而不是硬編碼為 1

sqlite3.version

此模組的版本號,以 字串 形式表示。這不是 SQLite 庫的版本。

自 3.12 版本起已棄用, 將在 3.14 版本中刪除: 此常量曾經反映 pysqlite 包的版本號,這是一個曾經將更改上游到 sqlite3 的第三方庫。如今,它沒有任何意義或實際價值。

sqlite3.version_info

此模組的版本號,以 tuple 形式的 整數 表示。這不是 SQLite 庫的版本。

自 3.12 版本起已棄用, 將在 3.14 版本中刪除: 此常量曾經反映 pysqlite 包的版本號,這是一個曾經將更改上游到 sqlite3 的第三方庫。如今,它沒有任何意義或實際價值。

sqlite3.SQLITE_DBCONFIG_DEFENSIVE
sqlite3.SQLITE_DBCONFIG_DQS_DDL
sqlite3.SQLITE_DBCONFIG_DQS_DML
sqlite3.SQLITE_DBCONFIG_ENABLE_FKEY
sqlite3.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
sqlite3.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
sqlite3.SQLITE_DBCONFIG_ENABLE_QPSG
sqlite3.SQLITE_DBCONFIG_ENABLE_TRIGGER
sqlite3.SQLITE_DBCONFIG_ENABLE_VIEW
sqlite3.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
sqlite3.SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
sqlite3.SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
sqlite3.SQLITE_DBCONFIG_RESET_DATABASE
sqlite3.SQLITE_DBCONFIG_TRIGGER_EQP
sqlite3.SQLITE_DBCONFIG_TRUSTED_SCHEMA
sqlite3.SQLITE_DBCONFIG_WRITABLE_SCHEMA

這些常量用於 Connection.setconfig()getconfig() 方法。

這些常量的可用性取決於 Python 編譯時使用的 SQLite 版本。

在 3.12 版本中新增。

另請參閱

https://www.sqlite.org/c3ref/c_dbconfig_defensive.html

SQLite 文件:資料庫連線配置選項

連線物件

class sqlite3.Connection

每個開啟的 SQLite 資料庫都由一個 Connection 物件表示,該物件使用 sqlite3.connect() 建立。它們的主要目的是建立 Cursor 物件和 事務控制

在 3.13 版本中更改: 如果在 Connection 物件被刪除之前沒有呼叫 close(),則會發出 ResourceWarning

SQLite 資料庫連線具有以下屬性和方法:

cursor(factory=Cursor)

建立並返回一個 Cursor 物件。cursor 方法接受一個可選引數 factory。如果提供,則它必須是返回 Cursor 或其子類例項的 可呼叫物件

blobopen(table, column, row, /, *, readonly=False, name='main')

開啟一個 Blob 控制代碼以訪問現有的 BLOB

引數:
  • table (str) – BLOB 所在的表的名稱。

  • column (str) – BLOB 所在的列的名稱。

  • row (str) – Blob 所在的行的名稱。

  • readonly (bool) – 如果應在沒有寫入許可權的情況下開啟 blob,則設定為 True。預設為 False

  • name (str) – Blob 所在的資料庫的名稱。預設為 "main"

Raises:

OperationalError – 嘗試在 WITHOUT ROWID 表中開啟 blob 時引發。

返回型別:

Blob

注意

無法使用 Blob 類更改 blob 的大小。使用 SQL 函式 zeroblob 建立具有固定大小的 blob。

在 3.11 版本中新增。

commit()

將任何掛起的事務提交到資料庫。如果 autocommitTrue,或者沒有開啟的事務,則此方法不執行任何操作。如果 autocommitFalse,則如果此方法提交了掛起的事務,則會隱式開啟一個新事務。

rollback()

回滾到任何掛起事務的開始。如果 autocommitTrue,或者沒有開啟的事務,則此方法不執行任何操作。如果 autocommitFalse,則如果此方法回滾了掛起的事務,則會隱式開啟一個新事務。

close()

關閉資料庫連線。如果 autocommitFalse,則會隱式回滾任何掛起的事務。如果 autocommitTrueLEGACY_TRANSACTION_CONTROL,則不執行隱式事務控制。請確保在關閉之前 commit() 以避免丟失掛起的更改。

execute(sql, parameters=(), /)

建立一個新的 Cursor 物件,並使用給定的 sqlparameters 呼叫其上的 execute()。返回新的遊標物件。

executemany(sql, parameters, /)

建立一個新的 Cursor 物件,並使用給定的 sqlparameters 呼叫其上的 executemany()。返回新的遊標物件。

executescript(sql_script, /)

建立一個新的 Cursor 物件,並使用給定的 sql_script 呼叫其上的 executescript()。返回新的遊標物件。

create_function(name, narg, func, *, deterministic=False)

建立或刪除使用者定義的 SQL 函式。

引數:
  • name (str) – SQL 函式的名稱。

  • narg (int) – SQL 函式可以接受的引數數量。如果為 -1,則可以接受任意數量的引數。

  • func (callback | None) – 當呼叫 SQL 函式時呼叫的 可呼叫 物件。可呼叫物件必須返回 SQLite 本機支援的型別。設定為 None 以刪除現有的 SQL 函式。

  • deterministic (bool) – 如果為 True,則建立的 SQL 函式將標記為 deterministic,這允許 SQLite 執行額外的最佳化。

在 3.8 版本中更改: 添加了 deterministic 引數。

示例

>>> import hashlib
>>> def md5sum(t):
...     return hashlib.md5(t).hexdigest()
>>> con = sqlite3.connect(":memory:")
>>> con.create_function("md5", 1, md5sum)
>>> for row in con.execute("SELECT md5(?)", (b"foo",)):
...     print(row)
('acbd18db4cc2f85cedef654fccc4a4d8',)
>>> con.close()

在 3.13 版本中更改: namenargfunc 作為關鍵字引數傳遞已被棄用。這些引數將在 Python 3.15 中變為僅限位置引數。

create_aggregate(name, n_arg, aggregate_class)

建立或刪除使用者定義的 SQL 聚合函式。

引數:
  • name (str) – SQL 聚合函式的名稱。

  • n_arg (int) – SQL 聚合函式可以接受的引數數量。如果為 -1,則可以接受任意數量的引數。

  • aggregate_class (class | None) –

    類必須實現以下方法

    step() 方法必須接受的引數數量由 n_arg 控制。

    設定為 None 以刪除現有的 SQL 聚合函式。

示例

class MySum:
    def __init__(self):
        self.count = 0

    def step(self, value):
        self.count += value

    def finalize(self):
        return self.count

con = sqlite3.connect(":memory:")
con.create_aggregate("mysum", 1, MySum)
cur = con.execute("CREATE TABLE test(i)")
cur.execute("INSERT INTO test(i) VALUES(1)")
cur.execute("INSERT INTO test(i) VALUES(2)")
cur.execute("SELECT mysum(i) FROM test")
print(cur.fetchone()[0])

con.close()

在 3.13 版本中更改: namen_argaggregate_class 作為關鍵字引數傳遞已被棄用。這些引數將在 Python 3.15 中變為僅限位置引數。

create_window_function(name, num_params, aggregate_class, /)

建立或刪除使用者定義的聚合視窗函式。

引數:
  • name (str) – 要建立或刪除的 SQL 聚合視窗函式的名稱。

  • num_params (int) – SQL 聚合視窗函式可以接受的引數數量。如果為 -1,則可以接受任意數量的引數。

  • aggregate_class (class | None) –

    一個必須實現以下方法的類

    • step(): 向當前視窗新增一行。

    • value(): 返回聚合的當前值。

    • inverse(): 從當前視窗刪除一行。

    • finalize(): 以 SQLite 本機支援的型別 返回聚合的最終結果。

    step()value() 方法必須接受的引數數量由 num_params 控制。

    設定為 None 以刪除現有的 SQL 聚合視窗函式。

Raises:

NotSupportedError – 如果與低於 3.25.0 版本的 SQLite 一起使用,該版本不支援聚合視窗函式。

在 3.11 版本中新增。

示例

# Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc
class WindowSumInt:
    def __init__(self):
        self.count = 0

    def step(self, value):
        """Add a row to the current window."""
        self.count += value

    def value(self):
        """Return the current value of the aggregate."""
        return self.count

    def inverse(self, value):
        """Remove a row from the current window."""
        self.count -= value

    def finalize(self):
        """Return the final value of the aggregate.

        Any clean-up actions should be placed here.
        """
        return self.count


con = sqlite3.connect(":memory:")
cur = con.execute("CREATE TABLE test(x, y)")
values = [
    ("a", 4),
    ("b", 5),
    ("c", 3),
    ("d", 8),
    ("e", 1),
]
cur.executemany("INSERT INTO test VALUES(?, ?)", values)
con.create_window_function("sumint", 1, WindowSumInt)
cur.execute("""
    SELECT x, sumint(y) OVER (
        ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
    ) AS sum_y
    FROM test ORDER BY x
""")
print(cur.fetchall())
con.close()
create_collation(name, callable, /)

使用排序函式 callable 建立名為 name 的排序規則。callable 接收兩個 字串 引數,並應返回一個 整數

  • 如果第一個引數的排序高於第二個引數,則返回 1

  • 如果第一個引數的排序低於第二個引數,則返回 -1

  • 如果它們的排序相同,則返回 0

以下示例展示了反向排序的排序規則:

def collate_reverse(string1, string2):
    if string1 == string2:
        return 0
    elif string1 < string2:
        return 1
    else:
        return -1

con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)

cur = con.execute("CREATE TABLE test(x)")
cur.executemany("INSERT INTO test(x) VALUES(?)", [("a",), ("b",)])
cur.execute("SELECT x FROM test ORDER BY x COLLATE reverse")
for row in cur:
    print(row)
con.close()

透過將 callable 設定為 None 來移除排序函式。

在 3.11 版本中更改: 排序規則名稱可以包含任何 Unicode 字元。之前,只允許使用 ASCII 字元。

interrupt()

從不同的執行緒呼叫此方法以中止可能正在連線上執行的任何查詢。被中止的查詢會引發一個 OperationalError

set_authorizer(authorizer_callback)

註冊 可呼叫物件 authorizer_callback,以便在每次嘗試訪問資料庫中表的列時呼叫。回撥應返回 SQLITE_OKSQLITE_DENYSQLITE_IGNORE 中的一個,以指示底層 SQLite 庫應如何處理對列的訪問。

回撥的第一個引數表示要授權的操作型別。第二個和第三個引數將是引數或 None,具體取決於第一個引數。第四個引數是資料庫的名稱(“main”、“temp”等),如果適用。第五個引數是負責訪問嘗試的最內層觸發器或檢視的名稱,如果此訪問嘗試直接來自輸入的 SQL 程式碼,則為 None

請查閱 SQLite 文件,瞭解第一個引數的可能值以及第二個和第三個引數的含義(取決於第一個引數)。所有必要的常量都可以在 sqlite3 模組中找到。

None 作為 authorizer_callback 傳遞將停用授權器。

在 3.11 版本中更改: 添加了使用 None 停用授權器的支援。

在 3.13 版本中更改: authorizer_callback 作為關鍵字引數傳遞已棄用。該引數將在 Python 3.15 中變為僅限位置引數。

set_progress_handler(progress_handler, n)

註冊 可呼叫物件 progress_handler,以便在 SQLite 虛擬機器每執行 n 條指令時呼叫。如果您想在長時間執行的操作期間從 SQLite 呼叫(例如,更新 GUI),這將非常有用。

如果要清除任何先前安裝的進度處理程式,請使用 None 作為 progress_handler 呼叫該方法。

從處理程式函式返回非零值將終止當前正在執行的查詢,並使其引發 DatabaseError 異常。

在 3.13 版本中更改: progress_handler 作為關鍵字引數傳遞已棄用。該引數將在 Python 3.15 中變為僅限位置引數。

set_trace_callback(trace_callback)

註冊 可呼叫物件 trace_callback,以便在 SQLite 後端實際執行每個 SQL 語句時呼叫。

傳遞給回撥的唯一引數是正在執行的語句(作為 str)。回撥的返回值將被忽略。請注意,後端不僅會執行傳遞給 Cursor.execute() 方法的語句。其他來源包括 sqlite3 模組的 事務管理 和當前資料庫中定義的觸發器的執行。

None 作為 trace_callback 傳遞將停用跟蹤回撥。

注意

跟蹤回撥中引發的異常不會傳播。作為開發和除錯輔助工具,請使用 enable_callback_tracebacks() 來啟用列印在跟蹤回撥中引發的異常的回溯。

在 3.3 版本中新增。

在 3.13 版本中更改: trace_callback 作為關鍵字引數傳遞已棄用。該引數將在 Python 3.15 中變為僅限位置引數。

enable_load_extension(enabled, /)

如果 enabledTrue,則允許 SQLite 引擎從共享庫載入 SQLite 擴充套件;否則,禁止載入 SQLite 擴充套件。SQLite 擴充套件可以定義新的函式、聚合或全新的虛擬表實現。一個著名的擴充套件是隨 SQLite 分發的全文搜尋擴充套件。

注意

預設情況下,sqlite3 模組不是使用可載入擴充套件支援構建的,因為某些平臺(尤其是 macOS)的 SQLite 庫在編譯時沒有此功能。要獲得可載入擴充套件支援,您必須將 --enable-loadable-sqlite-extensions 選項傳遞給 configure

使用引數 connectionenabled 引發 審計事件 sqlite3.enable_load_extension

在 3.2 版本中新增。

在 3.10 版本中更改: 添加了 sqlite3.enable_load_extension 審計事件。

con.enable_load_extension(True)

# Load the fulltext search extension
con.execute("select load_extension('./fts3.so')")

# alternatively you can load the extension using an API call:
# con.load_extension("./fts3.so")

# disable extension loading again
con.enable_load_extension(False)

# example from SQLite wiki
con.execute("CREATE VIRTUAL TABLE recipe USING fts3(name, ingredients)")
con.executescript("""
    INSERT INTO recipe (name, ingredients) VALUES('broccoli stew', 'broccoli peppers cheese tomatoes');
    INSERT INTO recipe (name, ingredients) VALUES('pumpkin stew', 'pumpkin onions garlic celery');
    INSERT INTO recipe (name, ingredients) VALUES('broccoli pie', 'broccoli cheese onions flour');
    INSERT INTO recipe (name, ingredients) VALUES('pumpkin pie', 'pumpkin sugar flour butter');
    """)
for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"):
    print(row)
load_extension(path, /, *, entrypoint=None)

從共享庫載入 SQLite 擴充套件。在呼叫此方法之前,使用 enable_load_extension() 啟用擴充套件載入。

引數:
  • path (str) – SQLite 擴充套件的路徑。

  • entrypoint (str | None) – 入口點名稱。如果為 None (預設值),SQLite 將自行生成一個入口點名稱;有關詳細資訊,請參閱 SQLite 文件 載入擴充套件

使用引數 connectionpath 引發 審計事件 sqlite3.load_extension

在 3.2 版本中新增。

在 3.10 版本中更改: 添加了 sqlite3.load_extension 審計事件。

在 3.12 版本中更改: 添加了 entrypoint 引數。

iterdump(*, filter=None)

返回一個 迭代器,用於將資料庫轉儲為 SQL 原始碼。在儲存記憶體資料庫以供以後恢復時很有用。類似於 sqlite3 shell 中的 .dump 命令。

引數:

filter (str | None) – 用於轉儲資料庫物件的可選 LIKE 模式,例如 prefix_%。如果為 None (預設值),則將包括所有資料庫物件。

示例

# Convert file example.db to SQL dump file dump.sql
con = sqlite3.connect('example.db')
with open('dump.sql', 'w') as f:
    for line in con.iterdump():
        f.write('%s\n' % line)
con.close()

在 3.13 版本中更改: 添加了 filter 引數。

backup(target, *, pages=-1, progress=None, name='main', sleep=0.250)

建立 SQLite 資料庫的備份。

即使資料庫正在被其他客戶端訪問,或者被同一連線併發訪問,也能正常工作。

引數:
  • target (Connection) – 用於儲存備份的資料庫連線。

  • pages (int) – 每次複製的頁數。如果等於或小於 0,則在單個步驟中複製整個資料庫。預設為 -1

  • progress (回撥 | None) – 如果設定為 可呼叫物件,則在每次備份迭代時都會使用三個整數引數呼叫它:上次迭代的狀態、仍需複製的剩餘頁數和頁數。預設為 None

  • name (str) – 要備份的資料庫的名稱。可以是主資料庫的 "main" (預設),臨時資料庫的 "temp",或者使用 ATTACH DATABASE SQL 語句附加的自定義資料庫的名稱。

  • sleep (float) – 連續嘗試備份剩餘頁之間休眠的秒數。

示例 1,將現有資料庫複製到另一個數據庫

def progress(status, remaining, total):
    print(f'Copied {total-remaining} of {total} pages...')

src = sqlite3.connect('example.db')
dst = sqlite3.connect('backup.db')
with dst:
    src.backup(dst, pages=1, progress=progress)
dst.close()
src.close()

示例 2,將現有資料庫複製到臨時副本

src = sqlite3.connect('example.db')
dst = sqlite3.connect(':memory:')
src.backup(dst)
dst.close()
src.close()

在 3.7 版本中新增。

getlimit(category, /)

獲取連線執行時限制。

引數:

category (int) – 要查詢的 SQLite 限制類別

返回型別:

int

Raises:

ProgrammingError – 如果底層 SQLite 庫無法識別 _category_。

示例,查詢 Connection con 的 SQL 語句最大長度 (預設為 1000000000)

>>> con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH)
1000000000

在 3.11 版本中新增。

setlimit(category, limit, /)

設定連線執行時限制。嘗試將限制增加到其硬上限以上時,將靜默截斷為硬上限。無論限制是否更改,都會返回限制的先前值。

引數:
  • category (int) – 要設定的 SQLite 限制類別

  • limit (int) – 新限制的值。如果為負數,則當前限制不變。

返回型別:

int

Raises:

ProgrammingError – 如果底層 SQLite 庫無法識別 _category_。

示例,將 Connection con 的附加資料庫數量限制為 1 (預設限制為 10)

>>> con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1)
10
>>> con.getlimit(sqlite3.SQLITE_LIMIT_ATTACHED)
1

在 3.11 版本中新增。

getconfig(op, /)

查詢布林連線配置選項。

引數:

op (int) – SQLITE_DBCONFIG 程式碼

返回型別:

bool

在 3.12 版本中新增。

setconfig(op, enable=True, /)

設定布林連線配置選項。

引數:

在 3.12 版本中新增。

serialize(*, name='main')

將資料庫序列化為 bytes 物件。對於普通的磁碟資料庫檔案,序列化只是磁碟檔案的副本。對於記憶體資料庫或“temp”資料庫,序列化是相同的位元組序列,如果將該資料庫備份到磁碟,則會寫入磁碟。

引數:

name (str) – 要序列化的資料庫名稱。預設為 "main"

返回型別:

bytes

注意

僅當底層 SQLite 庫具有序列化 API 時,此方法才可用。

在 3.11 版本中新增。

deserialize(data, /, *, name='main')

序列化 資料庫反序列化為 Connection。此方法導致資料庫連線斷開與資料庫 _name_ 的連線,並基於 _data_ 中包含的序列化重新開啟 _name_ 作為記憶體資料庫。

引數:
  • data (bytes) – 序列化的資料庫。

  • name (str) – 要反序列化到的資料庫名稱。預設為 "main"

Raises:

注意

僅當底層 SQLite 庫具有反序列化 API 時,此方法才可用。

在 3.11 版本中新增。

autocommit

此屬性控制 PEP 249 相容的事務行為。autocommit 允許三個值

autocommit 更改為 False 將開啟一個新的事務,將其更改為 True 將提交任何掛起的事務。

有關更多詳細資訊,請參見 透過 autocommit 屬性進行事務控制

注意

除非 autocommit 設定為 LEGACY_TRANSACTION_CONTROL,否則 isolation_level 屬性不會生效。

在 3.12 版本中新增。

in_transaction

此只讀屬性對應於底層的 SQLite 自動提交模式

如果事務處於活動狀態(有未提交的更改),則為 True;否則為 False

在 3.2 版本中新增。

isolation_level

控制 sqlite3舊式事務處理模式。 如果設定為 None,則永遠不會隱式開啟事務。 如果設定為 "DEFERRED""IMMEDIATE""EXCLUSIVE" 中的一個,則對應於底層的 SQLite 事務行為,將執行隱式事務管理

如果未被 connect()isolation_level 引數覆蓋,則預設值為 "",它是 "DEFERRED" 的別名。

注意

建議使用 autocommit 來控制事務處理,而不是使用 isolation_level。除非 autocommit 設定為 LEGACY_TRANSACTION_CONTROL(預設值),否則 isolation_level 不會生效。

row_factory

從此連線建立的 Cursor 物件的初始 row_factory。 對此屬性賦值不會影響此連線的現有遊標的 row_factory,只會影響新建立的遊標。 預設值為 None,表示每行都以 tuple 的形式返回。

有關更多詳細資訊,請參閱 如何建立和使用行工廠

text_factory

一個 可呼叫物件,它接受一個 bytes 引數,並返回其文字表示形式。 該可呼叫物件會為資料型別為 TEXT 的 SQLite 值呼叫。 預設情況下,此屬性設定為 str

有關更多詳細資訊,請參閱 如何處理非 UTF-8 文字編碼

total_changes

返回自資料庫連線開啟以來,已修改、插入或刪除的資料庫行總數。

遊標物件

Cursor 物件表示一個 資料庫遊標,它用於執行 SQL 語句並管理提取操作的上下文。 遊標使用 Connection.cursor() 建立,或者使用任何 連線快捷方式方法建立。

遊標物件是 迭代器,這意味著如果您 execute() 一個 SELECT 查詢,您可以簡單地迭代遊標來獲取結果行

for row in cur.execute("SELECT t FROM data"):
    print(row)
class sqlite3.Cursor

Cursor 例項具有以下屬性和方法。

execute(sql, parameters=(), /)

執行單個 SQL 語句,可以選擇使用 佔位符 繫結 Python 值。

引數:
Raises:

ProgrammingError – 如果 sql 包含多個 SQL 語句。

如果 autocommitLEGACY_TRANSACTION_CONTROLisolation_level 不為 NonesqlINSERTUPDATEDELETEREPLACE 語句,並且沒有開啟的事務,則在執行 sql 之前會隱式開啟一個事務。

自 3.12 版本起棄用,將在 3.14 版本中刪除:如果使用了 命名佔位符,並且 parameters 是序列而不是 dict,則會發出 DeprecationWarning。 從 Python 3.14 開始,將改為引發 ProgrammingError

使用 executescript() 執行多個 SQL 語句。

executemany(sql, parameters, /)

對於 parameters 中的每個項,重複執行 引數化DML SQL 語句 sql

使用與 execute() 相同的隱式事務處理。

引數:
Raises:

ProgrammingError – 如果 sql 包含多個 SQL 語句,或者不是 DML 語句。

示例

rows = [
    ("row1",),
    ("row2",),
]
# cur is an sqlite3.Cursor object
cur.executemany("INSERT INTO data VALUES(?)", rows)

注意

所有結果行都會被丟棄,包括帶有 RETURNING 子句的 DML 語句。

自 3.12 版本起已棄用,將在 3.14 版本中移除:如果使用了命名佔位符,並且parameters中的項是序列而不是dict,則會發出DeprecationWarning。 從 Python 3.14 開始,將改為引發ProgrammingError

executescript(sql_script, /)

執行 sql_script 中的 SQL 語句。 如果 autocommitLEGACY_TRANSACTION_CONTROL 並且存在待處理的事務,則首先執行隱式的 COMMIT 語句。 不執行其他隱式事務控制;任何事務控制都必須新增到 sql_script 中。

sql_script 必須是一個 字串

示例

# cur is an sqlite3.Cursor object
cur.executescript("""
    BEGIN;
    CREATE TABLE person(firstname, lastname, age);
    CREATE TABLE book(title, author, published);
    CREATE TABLE publisher(name, address);
    COMMIT;
""")
fetchone()

如果 row_factoryNone,則將下一個查詢結果集行作為 元組 返回。否則,將其傳遞給行工廠並返回其結果。如果沒有更多資料可用,則返回 None

fetchmany(size=cursor.arraysize)

將查詢結果的下一組行作為 列表 返回。如果沒有更多行可用,則返回空列表。

每次呼叫要提取的行數由 size 引數指定。如果未給出 size,則 arraysize 確定要提取的行數。如果可用行數少於 size,則返回所有可用的行。

請注意,size 引數涉及到效能方面的考慮。為了獲得最佳效能,通常最好使用 arraysize 屬性。如果使用 size 引數,則最好使其在從一個 fetchmany() 呼叫到下一個呼叫時保持相同的值。

fetchall()

將查詢結果的所有(剩餘)行作為 列表 返回。如果沒有可用的行,則返回空列表。請注意,arraysize 屬性可能會影響此操作的效能。

close()

立即關閉遊標(而不是在呼叫 __del__ 時)。

從此時起,遊標將無法使用;如果嘗試對遊標執行任何操作,將引發 ProgrammingError 異常。

setinputsizes(sizes, /)

DB-API 需要此項。在 sqlite3 中不起任何作用。

setoutputsize(size, column=None, /)

DB-API 需要此項。在 sqlite3 中不起任何作用。

arraysize

讀/寫屬性,用於控制 fetchmany() 返回的行數。 預設值為 1,這意味著每次呼叫將提取一行。

connection

只讀屬性,提供屬於該遊標的 SQLite 資料庫 Connection。透過呼叫 con.cursor() 建立的 Cursor 物件將具有一個 connection 屬性,該屬性引用 con

>>> con = sqlite3.connect(":memory:")
>>> cur = con.cursor()
>>> cur.connection == con
True
>>> con.close()
description

只讀屬性,提供上次查詢的列名。 為了與 Python DB API 保持相容,它為每一列返回一個 7 元組,其中每個元組的最後六項為 None

它也為沒有任何匹配行的 SELECT 語句設定。

lastrowid

只讀屬性,提供最後插入行的行 id。僅在使用 execute() 方法成功執行 INSERTREPLACE 語句後才會更新。對於其他語句,在 executemany()executescript() 之後,或者如果插入失敗,則 lastrowid 的值將保持不變。 lastrowid 的初始值為 None

注意

不會記錄插入到 WITHOUT ROWID 表中的資料。

在 3.6 版本中更改:添加了對 REPLACE 語句的支援。

rowcount

只讀屬性,提供 INSERTUPDATEDELETEREPLACE 語句的修改行數; 對於其他語句(包括CTE查詢)為 -1。它僅由 execute()executemany() 方法在語句執行完成後進行更新。這意味著必須提取任何結果行才能更新 rowcount

row_factory

控制如何表示從此 Cursor 中提取的行。如果為 None,則行表示為 元組。 可以設定為包含的 sqlite3.Row; 或者設定為一個可呼叫物件,該物件接受兩個引數,一個 Cursor 物件和行值的 tuple,並返回表示 SQLite 行的自定義物件。

預設值是建立 CursorConnection.row_factory 設定的值。 為此屬性賦值不會影響父連線的 Connection.row_factory

有關更多詳細資訊,請參閱 如何建立和使用行工廠

行物件

class sqlite3.Row

Row 例項用作 row_factory 的高度最佳化實現,用於 Connection 物件。 它支援迭代、相等性測試、len() 和按列名和索引的 對映 訪問。

如果兩個 Row 物件的列名和值都相同,則它們被認為是相等的。

有關更多詳細資訊,請參閱 如何建立和使用行工廠

keys()

返回列名列表,型別為 字串。 在查詢之後,它會是 Cursor.description 中每個元組的第一個成員。

在 3.5 版本中變更: 添加了切片的支援。

Blob 物件

class sqlite3.Blob

在 3.11 版本中新增。

Blob 例項是一個類檔案物件,它可以在 SQLite BLOB 中讀取和寫入資料。 呼叫 len(blob) 可以獲取 blob 的大小(位元組數)。 使用索引和切片 可以直接訪問 blob 資料。

使用 Blob 作為上下文管理器以確保在使用後關閉 blob 控制代碼。

con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE test(blob_col blob)")
con.execute("INSERT INTO test(blob_col) VALUES(zeroblob(13))")

# Write to our blob, using two write operations:
with con.blobopen("test", "blob_col", 1) as blob:
    blob.write(b"hello, ")
    blob.write(b"world.")
    # Modify the first and last bytes of our blob
    blob[0] = ord("H")
    blob[-1] = ord("!")

# Read the contents of our blob
with con.blobopen("test", "blob_col", 1) as blob:
    greeting = blob.read()

print(greeting)  # outputs "b'Hello, world!'"
con.close()
close()

關閉 blob。

從此時開始,blob 將不可用。 如果嘗試對 blob 執行任何進一步的操作,將引發 Error (或子類) 異常。

read(length=-1, /)

從當前偏移位置讀取 blob 中的 length 個位元組的資料。 如果到達 blob 的末尾,將返回直到 EOF 的資料。 當未指定 length 或為負數時,read() 將讀取直到 blob 的末尾。

write(data, /)

在當前偏移量將 data 寫入 blob。 此函式無法更改 blob 的長度。 寫入超出 blob 末尾的內容將引發 ValueError

tell()

返回 blob 的當前訪問位置。

seek(offset, origin=os.SEEK_SET, /)

將 blob 的當前訪問位置設定為 offsetorigin 引數預設為 os.SEEK_SET(絕對 blob 定位)。 origin 的其他值為 os.SEEK_CUR(相對於當前位置的查詢)和 os.SEEK_END(相對於 blob 末尾的查詢)。

PrepareProtocol 物件

class sqlite3.PrepareProtocol

PrepareProtocol 型別的唯一目的是作為 PEP 246 風格的適配協議,用於可以將自身適配原生 SQLite 型別的物件。

異常

異常層次結構由 DB-API 2.0 定義 (PEP 249)。

exception sqlite3.Warning

此異常目前不會由 sqlite3 模組引發,但可能會被使用 sqlite3 的應用程式引發,例如,如果使用者定義的函式在插入時截斷資料。 WarningException 的子類。

exception sqlite3.Error

此模組中其他異常的基類。 使用它可以透過一個 except 語句捕獲所有錯誤。 ErrorException 的子類。

如果異常源於 SQLite 庫內部,則以下兩個屬性將新增到該異常

sqlite_errorcode

來自 SQLite API 的數字錯誤程式碼

在 3.11 版本中新增。

sqlite_errorname

來自 SQLite API 的數字錯誤程式碼的符號名稱

在 3.11 版本中新增。

exception sqlite3.InterfaceError

由於濫用低階 SQLite C API 而引發的異常。 換句話說,如果引發此異常,則可能表示 sqlite3 模組中存在 bug。 InterfaceErrorError 的子類。

exception sqlite3.DatabaseError

由於與資料庫相關的錯誤而引發的異常。 這是幾種資料庫錯誤型別的基本異常。 它僅透過專門的子類隱式引發。 DatabaseErrorError 的子類。

exception sqlite3.DataError

由於處理的資料出現問題(如數值超出範圍和字串過長)而引發的異常。 DataErrorDatabaseError 的子類。

exception sqlite3.OperationalError

由於與資料庫操作相關的錯誤而引發的異常,這些錯誤不一定在程式設計師的控制之下。 例如,未找到資料庫路徑,或者無法處理事務。 OperationalErrorDatabaseError 的子類。

exception sqlite3.IntegrityError

當資料庫的關係完整性受到影響時引發的異常,例如,外部索引鍵檢查失敗。 它是 DatabaseError 的子類。

exception sqlite3.InternalError

當 SQLite 遇到內部錯誤時會引發此異常。如果引發此異常,可能表示執行時 SQLite 庫存在問題。InternalErrorDatabaseError 的子類。

exception sqlite3.ProgrammingError

sqlite3 API 程式設計出錯時會引發此異常,例如,為查詢提供的繫結數量不正確,或試圖對已關閉的 Connection 進行操作。ProgrammingErrorDatabaseError 的子類。

exception sqlite3.NotSupportedError

如果底層 SQLite 庫不支援某個方法或資料庫 API,則會引發此異常。例如,如果在底層 SQLite 庫不支援確定性函式的情況下,在 create_function() 中將 deterministic 設定為 TrueNotSupportedErrorDatabaseError 的子類。

SQLite 和 Python 型別

SQLite 本身支援以下型別:NULLINTEGERREALTEXTBLOB

因此,以下 Python 型別可以毫無問題地傳送到 SQLite

Python 型別

SQLite 型別

None

NULL

int

int

float

REAL

str

TEXT

bytes

bytes

BLOB

SQLite 型別

Python 型別

NULL

None

int

int

REAL

float

TEXT

這是預設情況下 SQLite 型別轉換為 Python 型別的方式

bytes

bytes

取決於 text_factory,預設為 str

sqlite3 模組的型別系統可以透過兩種方式擴充套件:您可以透過 物件介面卡 在 SQLite 資料庫中儲存其他 Python 型別,並且您可以透過 轉換器sqlite3 模組將 SQLite 型別轉換為 Python 型別。

注意

預設介面卡和轉換器(已棄用)

從 Python 3.12 開始,預設介面卡和轉換器已被棄用。請改用 介面卡和轉換器配方 並根據您的需要進行調整。

注意

用於將宣告的 “timestamp” 型別轉換為 datetime.datetime 物件的轉換器。小數部分將被截斷為 6 位數字(微秒精度)。

預設的 “timestamp” 轉換器會忽略資料庫中的 UTC 偏移量,並且始終返回一個樸素的 datetime.datetime 物件。若要保留時間戳中的 UTC 偏移量,可以停用轉換器,或者使用 register_converter() 註冊一個感知偏移量的轉換器。

自 3.12 版本起棄用。

命令列介面

python -m sqlite3 [-h] [-v] [filename] [sql]

可以使用直譯器的 -m 開關將 sqlite3 模組作為指令碼呼叫,以提供一個簡單的 SQLite shell。引數簽名如下所示

鍵入 .quit 或 CTRL-D 以退出 shell。

-h, --help

列印 CLI 幫助。

-v, --version

在 3.12 版本中新增。

列印底層 SQLite 庫的版本。

使用指南

如何在 SQL 查詢中使用佔位符繫結值

>>> # Never do this -- insecure!
>>> symbol = input()
' OR TRUE; --
>>> sql = "SELECT * FROM stocks WHERE symbol = '%s'" % symbol
>>> print(sql)
SELECT * FROM stocks WHERE symbol = '' OR TRUE; --'
>>> cur.execute(sql)

SQL 操作通常需要使用 Python 變數中的值。但是,請注意不要使用 Python 的字串操作來組裝查詢,因為它們容易受到 SQL 注入攻擊。例如,攻擊者可以簡單地關閉單引號並注入 OR TRUE 來選擇所有行

請改用 DB-API 的引數替換。若要在查詢字串中插入變數,請在該字串中使用佔位符,並透過將實際值作為元組提供給遊標的 execute() 方法的第二個引數,將實際值替換到查詢中。

con = sqlite3.connect(":memory:")
cur = con.execute("CREATE TABLE lang(name, first_appeared)")

# This is the named style used with executemany():
data = (
    {"name": "C", "year": 1972},
    {"name": "Fortran", "year": 1957},
    {"name": "Python", "year": 1991},
    {"name": "Go", "year": 2009},
)
cur.executemany("INSERT INTO lang VALUES(:name, :year)", data)

# This is the qmark style used in a SELECT query:
params = (1972,)
cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params)
print(cur.fetchall())
con.close()

注意

SQL 語句可以使用兩種佔位符之一:問號(qmark 樣式)或命名佔位符(命名樣式)。對於 qmark 樣式,parameters 必須是長度與佔位符數量匹配的 序列,否則會引發 ProgrammingError。對於命名樣式,parameters 必須是 dict(或其子類)的例項,其中必須包含所有命名引數的鍵;任何多餘的項都將被忽略。下面是兩種樣式的示例

PEP 249 數字佔位符*不*受支援。如果使用,它們將被解釋為命名佔位符。

如何將自定義 Python 型別適配到 SQLite 值

SQLite 本身僅支援有限的資料型別集。若要在 SQLite 資料庫中儲存自定義 Python 型別,請將它們適配SQLite 本身理解的 Python 型別 之一。

有兩種方法可以將 Python 物件適配到 SQLite 型別:讓您的物件自行適配,或者使用介面卡可呼叫物件。後者將優先於前者。對於匯出自定義型別的庫,啟用該型別自行適配可能是有意義的。作為應用程式開發人員,直接透過註冊自定義介面卡函式來控制可能更有意義。

如何編寫可適配的物件

class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __conform__(self, protocol):
        if protocol is sqlite3.PrepareProtocol:
            return f"{self.x};{self.y}"

con = sqlite3.connect(":memory:")
cur = con.cursor()

cur.execute("SELECT ?", (Point(4.0, -3.2),))
print(cur.fetchone()[0])
con.close()

假設我們有一個 Point 類,它表示笛卡爾座標系中的一對座標 xy。座標對將作為文字字串儲存在資料庫中,使用分號分隔座標。這可以透過新增一個 __conform__(self, protocol) 方法來實現,該方法返回適配的值。傳遞給 protocol 的物件將是 PrepareProtocol 型別。

如何註冊介面卡可呼叫物件

class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y

def adapt_point(point):
    return f"{point.x};{point.y}"

sqlite3.register_adapter(Point, adapt_point)

con = sqlite3.connect(":memory:")
cur = con.cursor()

cur.execute("SELECT ?", (Point(1.0, 2.5),))
print(cur.fetchone()[0])
con.close()

另一種可能性是建立一個函式,將 Python 物件轉換為與 SQLite 相容的型別。然後可以使用 register_adapter() 註冊此函式。

如何將 SQLite 值轉換為自定義 Python 型別

編寫介面卡允許您自定義 Python 型別轉換為 SQLite 值。為了能夠 SQLite 值轉換為自定義 Python 型別,我們使用轉換器

讓我們回到 Point 類。我們將 x 和 y 座標透過分號分隔,作為字串儲存在 SQLite 中。

注意

首先,我們將定義一個轉換器函式,該函式接受字串作為引數並從中構造一個 Point 物件。

def convert_point(s):
    x, y = map(float, s.split(b";"))
    return Point(x, y)

現在我們需要告訴 sqlite3 何時應該轉換給定的 SQLite 值。這在連線到資料庫時完成,使用 connect()detect_types 引數。有三種選擇

  • 隱式:將 detect_types 設定為 PARSE_DECLTYPES

  • 顯式:將 detect_types 設定為 PARSE_COLNAMES

  • 兩者:將 detect_types 設定為 sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES。列名優先於宣告的型別。

以下示例說明了隱式和顯式方法

class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

def adapt_point(point):
    return f"{point.x};{point.y}"

def convert_point(s):
    x, y = list(map(float, s.split(b";")))
    return Point(x, y)

# Register the adapter and converter
sqlite3.register_adapter(Point, adapt_point)
sqlite3.register_converter("point", convert_point)

# 1) Parse using declared types
p = Point(4.0, -3.2)
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.execute("CREATE TABLE test(p point)")

cur.execute("INSERT INTO test(p) VALUES(?)", (p,))
cur.execute("SELECT p FROM test")
print("with declared types:", cur.fetchone()[0])
cur.close()
con.close()

# 2) Parse using column names
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
cur = con.execute("CREATE TABLE test(p)")

cur.execute("INSERT INTO test(p) VALUES(?)", (p,))
cur.execute('SELECT p AS "p [point]" FROM test')
print("with column names:", cur.fetchone()[0])
cur.close()
con.close()

介面卡和轉換器配方

本節展示了常見介面卡和轉換器的配方。

import datetime
import sqlite3

def adapt_date_iso(val):
    """Adapt datetime.date to ISO 8601 date."""
    return val.isoformat()

def adapt_datetime_iso(val):
    """Adapt datetime.datetime to timezone-naive ISO 8601 date."""
    return val.isoformat()

def adapt_datetime_epoch(val):
    """Adapt datetime.datetime to Unix timestamp."""
    return int(val.timestamp())

sqlite3.register_adapter(datetime.date, adapt_date_iso)
sqlite3.register_adapter(datetime.datetime, adapt_datetime_iso)
sqlite3.register_adapter(datetime.datetime, adapt_datetime_epoch)

def convert_date(val):
    """Convert ISO 8601 date to datetime.date object."""
    return datetime.date.fromisoformat(val.decode())

def convert_datetime(val):
    """Convert ISO 8601 datetime to datetime.datetime object."""
    return datetime.datetime.fromisoformat(val.decode())

def convert_timestamp(val):
    """Convert Unix epoch timestamp to datetime.datetime object."""
    return datetime.datetime.fromtimestamp(int(val))

sqlite3.register_converter("date", convert_date)
sqlite3.register_converter("datetime", convert_datetime)
sqlite3.register_converter("timestamp", convert_timestamp)

如何使用連線快捷方法

使用 execute()executemany()executescript() 方法,你的程式碼可以寫得更簡潔,因為你不需要顯式建立(通常是多餘的) Cursor 物件。相反,Cursor 物件會被隱式建立,並且這些快捷方法會返回遊標物件。這樣,你可以執行一個 SELECT 語句,並直接使用 Connection 物件上的單個呼叫來迭代它。

# Create and fill the table.
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE lang(name, first_appeared)")
data = [
    ("C++", 1985),
    ("Objective-C", 1984),
]
con.executemany("INSERT INTO lang(name, first_appeared) VALUES(?, ?)", data)

# Print the table contents
for row in con.execute("SELECT name, first_appeared FROM lang"):
    print(row)

print("I just deleted", con.execute("DELETE FROM lang").rowcount, "rows")

# close() is not a shortcut method and it's not called automatically;
# the connection object should be closed manually
con.close()

如何使用連線上下文管理器

Connection 物件可以用作上下文管理器,在離開上下文管理器的主體時自動提交或回滾開啟的事務。如果 with 語句的主體在沒有異常的情況下完成,則事務將被提交。如果此提交失敗,或者 with 語句的主體引發了未捕獲的異常,則事務將被回滾。如果 autocommitFalse,則在提交或回滾後會隱式開啟一個新的事務。

如果在離開 with 語句的主體時沒有開啟的事務,或者如果 autocommitTrue,則上下文管理器不執行任何操作。

注意

上下文管理器既不會隱式開啟新的事務,也不會關閉連線。如果你需要一個關閉上下文管理器,請考慮使用 contextlib.closing()

con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE lang(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)")

# Successful, con.commit() is called automatically afterwards
with con:
    con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",))

# con.rollback() is called after the with block finishes with an exception,
# the exception is still raised and must be caught
try:
    with con:
        con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",))
except sqlite3.IntegrityError:
    print("couldn't add Python twice")

# Connection object used as context manager only commits or rollbacks transactions,
# so the connection object should be closed manually
con.close()

如何使用 SQLite URI

一些有用的 URI 技巧包括

  • 以只讀模式開啟資料庫

>>> con = sqlite3.connect("file:tutorial.db?mode=ro", uri=True)
>>> con.execute("CREATE TABLE readonly(data)")
Traceback (most recent call last):
OperationalError: attempt to write a readonly database
>>> con.close()
  • 如果新資料庫檔案不存在,則不要隱式建立;如果無法建立新檔案,則會引發 OperationalError

>>> con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True)
Traceback (most recent call last):
OperationalError: unable to open database file
  • 建立一個共享的命名記憶體資料庫

db = "file:mem1?mode=memory&cache=shared"
con1 = sqlite3.connect(db, uri=True)
con2 = sqlite3.connect(db, uri=True)
with con1:
    con1.execute("CREATE TABLE shared(data)")
    con1.execute("INSERT INTO shared VALUES(28)")
res = con2.execute("SELECT data FROM shared")
assert res.fetchone() == (28,)

con1.close()
con2.close()

有關此功能的更多資訊,包括引數列表,可以在 SQLite URI 文件中找到。

如何建立和使用行工廠

預設情況下,sqlite3 將每一行表示為 tuple。如果 tuple 不適合你的需求,你可以使用 sqlite3.Row 類或自定義的 row_factory

雖然 row_factory 作為 CursorConnection 上的屬性存在,但建議設定 Connection.row_factory,以便從連線建立的所有遊標都使用相同的行工廠。

Row 提供對列的索引訪問和不區分大小寫的命名訪問,與 tuple 相比,記憶體開銷和效能影響最小。要使用 Row 作為行工廠,請將其分配給 row_factory 屬性

>>> con = sqlite3.connect(":memory:")
>>> con.row_factory = sqlite3.Row

現在,查詢會返回 Row 物件

>>> res = con.execute("SELECT 'Earth' AS name, 6378 AS radius")
>>> row = res.fetchone()
>>> row.keys()
['name', 'radius']
>>> row[0]         # Access by index.
'Earth'
>>> row["name"]    # Access by name.
'Earth'
>>> row["RADIUS"]  # Column names are case-insensitive.
6378
>>> con.close()

注意

在上面的例子中,SELECT 語句中可以省略 FROM 子句。在這種情況下,SQLite 會返回一個單行,其列由表示式定義,例如帶有給定別名 expr AS alias 的字面量。

你可以建立一個自定義的 row_factory,它將每一行作為 dict 返回,其中列名對映到值

def dict_factory(cursor, row):
    fields = [column[0] for column in cursor.description]
    return {key: value for key, value in zip(fields, row)}

使用它,查詢現在會返回一個 dict,而不是一個 tuple

>>> con = sqlite3.connect(":memory:")
>>> con.row_factory = dict_factory
>>> for row in con.execute("SELECT 1 AS a, 2 AS b"):
...     print(row)
{'a': 1, 'b': 2}
>>> con.close()

以下行工廠返回一個 named tuple

from collections import namedtuple

def namedtuple_factory(cursor, row):
    fields = [column[0] for column in cursor.description]
    cls = namedtuple("Row", fields)
    return cls._make(row)

namedtuple_factory() 可以如下使用

>>> con = sqlite3.connect(":memory:")
>>> con.row_factory = namedtuple_factory
>>> cur = con.execute("SELECT 1 AS a, 2 AS b")
>>> row = cur.fetchone()
>>> row
Row(a=1, b=2)
>>> row[0]  # Indexed access.
1
>>> row.b   # Attribute access.
2
>>> con.close()

經過一些調整,上述配方可以被改編為使用 dataclass,或任何其他自定義類,而不是 namedtuple

如何處理非 UTF-8 文字編碼

預設情況下,sqlite3 使用 str 來適配具有 TEXT 資料型別的 SQLite 值。這對於 UTF-8 編碼的文字效果很好,但對於其他編碼和無效的 UTF-8 可能會失敗。你可以使用自定義的 text_factory 來處理這種情況。

由於 SQLite 的靈活型別,遇到包含非 UTF-8 編碼甚至任意資料的 TEXT 資料型別表列是很常見的。為了演示,假設我們有一個數據庫,其中包含 ISO-8859-2 (Latin-2) 編碼的文字,例如一個捷克語-英語詞典條目表。假設我們現在有一個連線到此資料庫的 Connection 例項 con,我們可以使用此 text_factory 解碼 Latin-2 編碼的文字

con.text_factory = lambda data: str(data, encoding="latin2")

對於儲存在 TEXT 表列中的無效 UTF-8 或任意資料,可以使用以下技術,該技術借鑑自Unicode HOWTO

con.text_factory = lambda data: str(data, errors="surrogateescape")

注意

sqlite3 模組 API 不支援包含代理項的字串。

另請參閱

Unicode HOWTO

解釋

事務控制

sqlite3 提供了多種控制資料庫事務何時、如何以及是否開啟和關閉的方法。透過 autocommit 屬性進行事務控制 是推薦的方法,而透過 isolation_level 屬性進行事務控制 則保留了 Python 3.12 之前的行為。

透過 autocommit 屬性進行事務控制

控制事務行為的推薦方法是透過 Connection.autocommit 屬性,該屬性最好使用 connect() 的 *autocommit* 引數進行設定。

建議將 *autocommit* 設定為 False,這意味著符合 PEP 249 的事務控制。這意味著

  • sqlite3 確保事務始終處於開啟狀態,因此 connect()Connection.commit()Connection.rollback() 將隱式開啟新事務(對於後兩者,將在關閉待處理事務後立即開啟)。當開啟事務時,sqlite3 使用 BEGIN DEFERRED 語句。

  • 應該使用 commit() 顯式提交事務。

  • 應該使用 rollback() 顯式回滾事務。

  • 如果資料庫在有待處理更改的情況下被 close(),則會執行隱式回滾。

將 *autocommit* 設定為 True 以啟用 SQLite 的自動提交模式。在此模式下,Connection.commit()Connection.rollback() 沒有效果。請注意,SQLite 的自動提交模式與符合 PEP 249Connection.autocommit 屬性不同;使用 Connection.in_transaction 查詢底層 SQLite 自動提交模式。

將 *autocommit* 設定為 LEGACY_TRANSACTION_CONTROL,將事務控制行為留給 Connection.isolation_level 屬性。有關更多資訊,請參閱透過 isolation_level 屬性進行事務控制

透過 isolation_level 屬性進行事務控制

注意

控制事務的推薦方法是透過 autocommit 屬性。請參閱 透過 autocommit 屬性進行事務控制

如果 Connection.autocommit 設定為 LEGACY_TRANSACTION_CONTROL(預設值),則事務行為由 Connection.isolation_level 屬性控制。否則,isolation_level 沒有效果。

如果連線屬性 isolation_level 不為 None,則在 execute()executemany() 執行 INSERTUPDATEDELETEREPLACE 語句之前,會隱式開啟新事務;對於其他語句,不執行隱式事務處理。使用 commit()rollback() 方法分別提交和回滾待處理事務。您可以選擇底層的SQLite 事務行為——也就是說,sqlite3 隱式執行的 BEGIN 語句的型別和執行方式——透過 isolation_level 屬性。

如果 isolation_level 設定為 None,則根本不會隱式開啟任何事務。這會將底層 SQLite 庫置於自動提交模式,但也允許使用者使用顯式 SQL 語句執行自己的事務處理。可以使用 in_transaction 屬性查詢底層 SQLite 庫的自動提交模式。

無論 isolation_level 的值如何,executescript() 方法都會在執行給定的 SQL 指令碼之前隱式提交任何待處理的事務。

在 3.6 版本中更改:sqlite3 曾經在 DDL 語句之前隱式提交開啟的事務。現在不再這樣了。

在 3.12 版本中更改:現在,控制事務的推薦方法是透過 autocommit 屬性。