跳转至

SQLite 嵌入式数据库

SQLite 是一个嵌入式的轻量级关系型数据库,不需要安装服务器,整个数据库就是一个文件,Python 标准库自带支持,特别适合小型项目、本地数据存储和快速原型开发。

核心知识点

知识点说明
数据库类型嵌入式关系型数据库(无服务器)
最新版本SQLite 3.47+(持续更新)
核心特点零配置、单文件存储、跨平台、Python 内置
适用场景本地应用、原型开发、数据分析、测试、移动端
不适用场景高并发写入、大规模 Web 应用(用 PostgreSQL)
数据大小单数据库最大 281 TB
Python 支持标准库 sqlite3 模块,无需额外安装

安装配置

Python 内置(无需安装)

import sqlite3  # Python 标准库自带,直接导入即可
print(sqlite3.sqlite_version)  # 查看 SQLite 版本

命令行工具安装

# Ubuntu/Debian
sudo apt install sqlite3             # 安装命令行工具

# macOS(自带)
sqlite3 --version                     # 查看版本

# Conda
conda install -c conda-forge sqlite  # 安装

基本使用

1. 命令行操作

# 创建/打开数据库
sqlite3 bioinfo.db                    # 打开(不存在则创建)

# SQLite 命令(以 . 开头的是 SQLite 特有命令)
.databases                            # 查看已打开的数据库
.tables                               # 列出所有表
.schema samples                       # 查看表结构
.mode column                          # 列对齐显示
.headers on                           # 显示列名
.quit                                 # 退出

2. Python 基本操作

import sqlite3  # 导入 sqlite3 模块

# 连接数据库(文件不存在会自动创建)
conn = sqlite3.connect("bioinfo.db")  # 连接到 bioinfo.db
cursor = conn.cursor()                 # 创建游标

# 创建表
cursor.execute("""
    CREATE TABLE IF NOT EXISTS samples (
        id INTEGER PRIMARY KEY AUTOINCREMENT,   -- 自增主键
        sample_id TEXT UNIQUE NOT NULL,         -- 样本 ID
        diagnosis TEXT NOT NULL,                -- 诊断
        bmi REAL,                              -- BMI(浮点数)
        created_at TEXT DEFAULT (datetime('now'))  -- 创建时间
    )
""")

# 插入数据
cursor.execute(
    "INSERT INTO samples (sample_id, diagnosis, bmi) VALUES (?, ?, ?)",
    ("T2D_001", "T2D", 28.5)           # 用 ? 占位符防止 SQL 注入
)

# 批量插入
data = [
    ("T2D_002", "T2D", 30.1),
    ("HC_001", "Healthy", 22.0),
    ("HC_002", "Healthy", 21.5),
]
cursor.executemany(
    "INSERT INTO samples (sample_id, diagnosis, bmi) VALUES (?, ?, ?)",
    data                                # 批量插入列表
)

conn.commit()  # 提交事务(重要!不提交数据会丢失)

# 查询
cursor.execute("SELECT * FROM samples WHERE diagnosis = ?", ("T2D",))
for row in cursor.fetchall():          # 获取所有结果
    print(row)

# 关闭
conn.close()

3. 与 Pandas 结合(生信数据分析利器)

import pandas as pd  # 导入 pandas
import sqlite3       # 导入 sqlite3

conn = sqlite3.connect("bioinfo.db")

# 从 CSV 导入到 SQLite
df = pd.read_csv("abundance_table.csv")  # 读取 CSV
df.to_sql("abundance", conn, if_exists="replace", index=False)  # 写入数据库

# 用 SQL 查询,直接返回 DataFrame
result = pd.read_sql_query("""
    SELECT sample_id, diagnosis, bmi
    FROM samples
    WHERE bmi > 25
    ORDER BY bmi DESC
""", conn)  # SQL 查询结果直接变 DataFrame
print(result)

# 复杂查询也没问题
result = pd.read_sql_query("""
    SELECT s.sample_id, s.diagnosis, a.Bacteroides
    FROM samples s
    JOIN abundance a ON s.sample_id = a.sample_id
    WHERE s.diagnosis = 'T2D'
""", conn)

conn.close()

高级用法

1. 内存数据库(极速临时分析)

import sqlite3

# 内存数据库(关闭连接后数据消失,但速度极快)
conn = sqlite3.connect(":memory:")  # 使用 :memory: 创建内存数据库
cursor = conn.cursor()

# 适合临时数据处理
cursor.execute("CREATE TABLE temp_data (id INTEGER, value REAL)")
cursor.executemany("INSERT INTO temp_data VALUES (?, ?)",
    [(i, i * 0.5) for i in range(100000)])  # 插入 10 万行

cursor.execute("SELECT AVG(value), MAX(value) FROM temp_data")
print(cursor.fetchone())  # 瞬间完成

conn.close()  # 关闭后数据自动消失

2. 使用上下文管理器(自动提交/回滚)

import sqlite3

# 推荐用 with 语句,自动处理提交和回滚
with sqlite3.connect("bioinfo.db") as conn:
    conn.execute("INSERT INTO samples (sample_id, diagnosis) VALUES (?, ?)",
                 ("T2D_010", "T2D"))
    # with 块结束时自动 commit
    # 如果出错会自动 rollback

3. 自定义函数

import sqlite3
import math

conn = sqlite3.connect("bioinfo.db")

# 注册自定义函数(SQLite 原生不支持的功能)
conn.create_function("log2", 1, lambda x: math.log2(x) if x > 0 else None)

# 现在可以在 SQL 中使用 log2
cursor = conn.cursor()
cursor.execute("SELECT sample_id, log2(bmi) FROM samples")
for row in cursor.fetchall():
    print(row)

conn.close()

4. 全文搜索(FTS5)

-- 创建全文搜索表
CREATE VIRTUAL TABLE notes_fts USING fts5(
    title,       -- 标题
    content,     -- 内容
    tags         -- 标签
);

-- 插入数据
INSERT INTO notes_fts VALUES (
    'T2D 肠道菌群研究',
    '2型糖尿病患者的肠道菌群多样性显著降低',
    'T2D microbiome diversity'
);

-- 全文搜索
SELECT * FROM notes_fts WHERE notes_fts MATCH 'microbiome';     -- 搜索关键词
SELECT * FROM notes_fts WHERE notes_fts MATCH 'T2D AND diversity';  -- 组合搜索

5. 数据库备份和导出

import sqlite3

# 备份到另一个文件
source = sqlite3.connect("bioinfo.db")
backup = sqlite3.connect("bioinfo_backup.db")
source.backup(backup)  # 一行代码完成备份
backup.close()
source.close()
# 命令行导出
sqlite3 bioinfo.db .dump > backup.sql       # 导出为 SQL
sqlite3 bioinfo.db ".mode csv" ".headers on" "SELECT * FROM samples;" > samples.csv  # 导出 CSV

常见报错与解决

报错信息原因解决方法
database is locked多个进程同时写入timeout 参数或改用 WAL 模式
UNIQUE constraint failed唯一键重复INSERT OR REPLACEINSERT OR IGNORE
no such table表不存在检查表名,用 .tables 确认
OperationalError: unable to open database文件路径错或权限不够检查路径和文件权限
数据丢失忘了 conn.commit()务必在写操作后提交,或用 with 语句
disk I/O error磁盘满或文件系统错误检查磁盘空间

速查表

# ===== SQLite 速查表 =====

import sqlite3
import pandas as pd

# === 连接 ===
conn = sqlite3.connect("data.db")     # 文件数据库
conn = sqlite3.connect(":memory:")    # 内存数据库

# === 基本操作 ===
cursor = conn.cursor()
cursor.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT)")
cursor.execute("INSERT INTO t (name) VALUES (?)", ("test",))
cursor.execute("SELECT * FROM t WHERE name = ?", ("test",))
rows = cursor.fetchall()              # 获取所有行
conn.commit()                         # 提交
conn.close()                          # 关闭

# === 与 Pandas 结合 ===
df = pd.read_sql_query("SELECT * FROM t", conn)  # SQL → DataFrame
df.to_sql("t", conn, if_exists="replace")         # DataFrame → SQL

# === WAL 模式(提升并发性能)===
conn.execute("PRAGMA journal_mode=WAL")

# === 命令行 ===
# sqlite3 data.db                    打开数据库
# .tables                            列出表
# .schema table                      表结构
# .mode csv / .mode column           显示模式
# .headers on                        显示列名
# .dump                              导出 SQL
# .quit                              退出

# === SQLite vs PostgreSQL ===
# SQLite:单文件、零配置、适合小项目
# PostgreSQL:服务器模式、高并发、适合生产环境