1. python3连接sqlite3的完整指南
sqlite作为轻量级数据库引擎,在python生态中有着广泛的应用场景。无论是开发原型系统、移动应用还是嵌入式设备,sqlite3模块都是python开发者不可或缺的工具。本文将深入讲解python3操作sqlite3的完整流程,包含连接管理、crud操作、事务控制等核心知识点。
1.1 环境准备与基础连接
python标准库已内置sqlite3模块,无需额外安装。建立数据库连接是最基础的操作:
import sqlite3
# 创建内存数据库(临时)
conn = sqlite3.connect(':memory:')
# 创建/连接磁盘数据库文件
conn = sqlite3.connect('example.db')
# 使用with语句自动管理连接
with sqlite3.connect('example.db') as conn:
pass # 数据库操作代码连接参数说明:
:memory:表示创建内存数据库,程序退出后数据消失- 文件路径则创建持久化数据库,若文件不存在会自动创建
- 推荐使用with语句管理连接,可自动处理连接的关闭
注意:sqlite是服务器进程的数据库引擎,所有操作都在本地完成。连接对象是线程不安全的,多线程环境需要为每个线程创建独立连接。
1.2 连接参数详解
connect()方法支持多个可选参数:
conn = sqlite3.connect(
'example.db',
timeout=5.0, # 等待锁的超时时间(秒)
detect_types=sqlite3.parse_decltypes, # 类型检测模式
isolation_level=none, # 事务隔离级别
check_same_thread=true # 是否检查线程安全
)关键参数解析:
timeout:当多个连接访问同一数据库时的等待超时detect_types:启用类型转换(parse_decltypes/parse_colnames)isolation_level:控制事务行为(none/"deferred"/"immediate"/"exclusive")
2. 基本crud操作
2.1 创建表与插入数据
通过cursor对象执行sql语句:
# 获取游标对象
cursor = conn.cursor()
# 创建表
cursor.execute('''
create table if not exists users (
id integer primary key autoincrement,
name text not null,
age integer,
created_at timestamp default current_timestamp
)
''')
# 插入单条数据(安全的方式)
cursor.execute(
'insert into users (name, age) values (?, ?)',
('alice', 25)
)
# 插入多条数据
users = [
('bob', 30),
('charlie', 35),
('david', 40)
]
cursor.executemany(
'insert into users (name, age) values (?, ?)',
users
)
# 提交事务
conn.commit()重要:始终使用参数化查询(?占位符)而非字符串拼接,可防止sql注入攻击。
2.2 查询与结果处理
查询结果可以通过多种方式获取:
# 查询所有记录
cursor.execute('select * from users')
all_rows = cursor.fetchall() # 获取全部结果
# 逐行获取
cursor.execute('select * from users')
for row in cursor:
print(row)
# 获取单条记录
cursor.execute('select * from users where id = ?', (1,))
user = cursor.fetchone()
# 使用字典形式返回结果
conn.row_factory = sqlite3.row
cursor = conn.cursor()
cursor.execute('select * from users where id = ?', (1,))
user = cursor.fetchone()
print(user['name']) # 通过列名访问结果处理技巧:
fetchall():返回所有行的列表fetchone():返回下一行fetchmany(size):返回指定数量的行- 设置
row_factory可改变返回结果的格式
2.3 更新与删除操作
更新和删除操作同样使用execute方法:
# 更新数据
cursor.execute(
'update users set age = ? where name = ?',
(26, 'alice')
)
# 删除数据
cursor.execute(
'delete from users where id = ?',
(5,)
)
# 获取受影响的行数
print(f"rows affected: {cursor.rowcount}")
conn.commit()3. 高级特性与应用
3.1 事务控制
sqlite支持完整的事务特性:
try:
# 开始事务(默认自动开始)
cursor.execute("begin")
# 执行多个操作
cursor.execute("insert into users (name) values ('eve')")
cursor.execute("update users set age = 20 where name = 'eve'")
# 提交事务
conn.commit()
except exception as e:
# 出错时回滚
conn.rollback()
print(f"transaction failed: {e}")事务模式说明:
isolation_level=none:自动提交模式(非标准)isolation_level="deferred":延迟锁获取(默认)isolation_level="immediate":立即获取保留锁isolation_level="exclusive":获取独占锁
3.2 自定义函数与聚合
可以在sql中注册python函数:
# 注册标量函数
def reverse_string(s):
return s[::-1]
conn.create_function("reverse", 1, reverse_string)
# 在sql中使用
cursor.execute("select reverse(name) from users")
print(cursor.fetchall())
# 注册聚合函数
class average:
def __init__(self):
self.sum = 0
self.count = 0
def step(self, value):
self.sum += value
self.count += 1
def finalize(self):
return self.sum / self.count if self.count else 0
conn.create_aggregate("avg_py", 1, average)
cursor.execute("select avg_py(age) from users")
print(cursor.fetchone()[0])3.3 类型适配与转换
处理非标准数据类型:
import datetime
# 适配python日期到sqlite
def adapt_date(date):
return date.isoformat()
sqlite3.register_adapter(datetime.date, adapt_date)
# 转换sqlite值到python日期
def convert_date(s):
return datetime.date.fromisoformat(s.decode())
sqlite3.register_converter("date", convert_date)
# 使用类型检测
conn = sqlite3.connect(
'example.db',
detect_types=sqlite3.parse_decltypes
)
cursor.execute('''
create table events (
id integer primary key,
name text,
event_date date
)
''')
today = datetime.date.today()
cursor.execute(
'insert into events (name, event_date) values (?, ?)',
('conference', today)
)
cursor.execute('select event_date from events')
event = cursor.fetchone()
print(type(event[0])) # <class 'datetime.date'>4. 性能优化与最佳实践
4.1 批量操作优化
大量数据插入时使用特殊技巧:
# 1. 使用executemany(中等规模数据)
data = [(f'user_{i}', i) for i in range(1000)]
cursor.executemany(
'insert into users (name, age) values (?, ?)',
data
)
# 2. 显式事务(大数据量)
conn.execute("begin")
try:
for i in range(10000):
cursor.execute(
'insert into users (name, age) values (?, ?)',
(f'user_{i}', i)
)
conn.commit()
except:
conn.rollback()
raise
# 3. 使用备份api(超大数据量)
conn.execute("create table big_data (id integer, data text)")
conn.execute("begin")
for i in range(100000):
if i % 1000 == 0:
conn.commit()
conn.execute("begin")
conn.execute(
"insert into big_data values (?, ?)",
(i, 'x'*100)
)
conn.commit()4.2 索引与查询优化
# 创建索引
cursor.execute('create index idx_users_age on users(age)')
# 分析查询计划
cursor.execute('explain query plan select * from users where age > 30')
print(cursor.fetchall())
# 使用覆盖索引
cursor.execute('create index idx_users_covering on users(name, age)')
cursor.execute('select name, age from users where age between 20 and 30')4.3 常见问题排查
- 数据库锁定问题 :
- 错误:
sqlite3.operationalerror: database is locked - 解决方案:增加timeout参数,优化事务范围
- 错误:
- 类型转换错误 :
- 错误:
sqlite3.interfaceerror: error binding parameter - 检查:确保参数类型与字段类型匹配
- 内存管理 :
- 对于大型查询,使用迭代而非fetchall:
cursor.execute('select * from large_table')
for row in cursor:
process(row) # 逐行处理,避免内存爆炸
- 连接泄漏 :
- 始终确保连接被关闭:
# 正确做法
with sqlite3.connect('db.sqlite') as conn:
# 操作代码
# 或者显式关闭
try:
conn = sqlite3.connect('db.sqlite')
# 操作代码
finally:
conn.close()5. 实际应用案例
5.1 web应用中的使用
from flask import flask, g
app = flask(__name__)
def get_db():
if 'db' not in g:
g.db = sqlite3.connect('app.db')
g.db.row_factory = sqlite3.row
return g.db
@app.teardown_appcontext
def close_db(e=none):
db = g.pop('db', none)
if db is not none:
db.close()
@app.route('/users')
def list_users():
db = get_db()
users = db.execute('select * from users').fetchall()
return {'users': [dict(user) for user in users]}5.2 数据分析应用
import sqlite3
import pandas as pd
# 将sqlite数据加载到pandas
with sqlite3.connect('data.db') as conn:
df = pd.read_sql('select * from sales', conn)
# 使用pandas分析后写回sqlite
with sqlite3.connect('report.db') as conn:
df.groupby('category').sum().to_sql(
'sales_summary',
conn,
if_exists='replace'
)5.3 嵌入式设备应用
# 在树莓派等设备上的典型用法
import sqlite3
from sensors import read_temperature
db_path = '/mnt/sd_card/data.db'
def init_db():
conn = sqlite3.connect(db_path)
conn.execute('''
create table if not exists readings (
timestamp datetime default current_timestamp,
value real
)
''')
conn.commit()
conn.close()
def log_reading(value):
conn = sqlite3.connect(db_path)
conn.execute('insert into readings (value) values (?)', (value,))
conn.commit()
conn.close()
# 定时记录传感器数据
init_db()
while true:
temp = read_temperature()
log_reading(temp)
time.sleep(60)6. 安全注意事项
- sql注入防护 :
- 永远不要使用字符串拼接构造sql
- 始终使用参数化查询:
# 危险!
cursor.execute(f"select * from users where name = '{user_input}'")
# 安全
cursor.execute("select * from users where name = ?", (user_input,))- 数据验证 :
- 对所有输入数据进行验证和清理
- 使用白名单验证复杂输入
- 敏感数据保护 :
- sqlite不提供内置加密(社区版本)
- 对敏感数据考虑应用层加密
- 使用sqlcipher等加密版本处理敏感数据
- 备份策略 :
# 简单备份方法
def backup_db(src_path, dst_path):
src = sqlite3.connect(src_path)
dst = sqlite3.connect(dst_path)
with dst:
src.backup(dst)
src.close()
dst.close()在实际项目中,根据具体需求选择合适的sqlite使用模式。对于简单的数据存储需求,直接使用python标准库的sqlite3模块即可;对于复杂应用,可以考虑结合sqlalchemy等orm工具使用。
到此这篇关于python3操作sqlite3数据库的完整指南(最新推荐)的文章就介绍到这了,更多相关python3操作sqlite3数据库内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论