本文目录导读:

完全可以,而且用脚本自动管理 SQLite 数据库是非常实用且常见的做法,无论是备份、迁移、清理、定期维护,还是执行复杂的数据库操作,脚本都能把这些任务从手动操作中解放出来。
你可以用多种脚本语言来完成这个任务,最常见的是 Shell 脚本(Linux/macOS)和 Python(跨平台),下面我会分为两种主要场景来介绍实用脚本的写法。
使用 Shell 脚本(Linux/macOS 环境)
Shell 脚本非常轻量,适合在服务器上作为定时任务(Cron Job)执行,它可以直接调用 sqlite3 命令行工具。
核心功能:数据库备份
一个简单的备份脚本,自动生成带时间戳的备份文件。
脚本文件:backup_sqlite.sh
#!/bin/bash # 配置区域 DB_PATH="/path/to/your/database.db" BACKUP_DIR="/path/to/backup/folder" TIMESTAMP=$(date +"%Y%m%d_%H%M%S") BACKUP_FILE="$BACKUP_DIR/db_backup_$TIMESTAMP.db" # 创建备份目录(如果不存在) mkdir -p $BACKUP_DIR # 执行备份 (sqlite3 .backup 命令是最安全的方式,防止写损坏) sqlite3 $DB_PATH ".backup $BACKUP_FILE" # 可选:删除7天前的旧备份 find $BACKUP_DIR -name "db_backup_*.db" -type f -mtime +7 -delete echo "Backup completed: $BACKUP_FILE"
如何运行:
- 添加执行权限:
chmod +x backup_sqlite.sh - 手动运行:
./backup_sqlite.sh - 设置定时任务(每天凌晨2点):在终端输入
crontab -e然后添加:0 2 * * * /path/to/backup_sqlite.sh
核心功能:数据库优化与清理
SQLite 数据库在频繁删除和插入后,文件大小可能不会自动缩小,需要定期执行 VACUUM 和 REINDEX。
脚本文件:optimize_sqlite.sh
#!/bin/bash DB_PATH="/path/to/your/database.db" LOG_FILE="/var/log/sqlite_optimize.log" # 记录开始时间 echo "=== Optimization started at $(date) ===" >> $LOG_FILE # 执行 VACUUM(重建数据库文件,回收空间) sqlite3 $DB_PATH "VACUUM;" echo "VACUUM done." >> $LOG_FILE # 执行 ANALYZE(更新查询优化器的统计信息) sqlite3 $DB_PATH "ANALYZE;" echo "ANALYZE done." >> $LOG_FILE # 执行 REINDEX(重新建立索引,解决索引碎片) sqlite3 $DB_PATH "REINDEX;" echo "REINDEX done." >> $LOG_FILE # 可选:执行完整性检查 sqlite3 $DB_PATH "PRAGMA integrity_check;" >> $LOG_FILE echo "=== Optimization finished at $(date) ===" >> $LOG_FILE
使用 Python 脚本(跨平台,功能更强大)
Python 的 sqlite3 模块是标准库的一部分,无需额外安装,并且可以处理更复杂的逻辑,比如数据迁移、条件性清理、发送通知等。
核心功能:自动化数据归档(删除旧数据)
假设你有一个日志表 logs,想自动删除 30 天前的记录,并记录删除条数。
脚本文件:archive_old_data.py
#!/usr/bin/env python3
import sqlite3
import datetime
DB_PATH = "/path/to/your/database.db"
RETENTION_DAYS = 30 # 保留最近30天的数据
def archive_old_records():
try:
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
# 计算30天前的日期
cutoff_date = datetime.datetime.now() - datetime.timedelta(days=RETENTION_DAYS)
cutoff_str = cutoff_date.strftime("%Y-%m-%d %H:%M:%S")
# 删除旧记录,并获取删除了多少行
cursor.execute("DELETE FROM logs WHERE created_at < ?", (cutoff_str,))
deleted_count = cursor.rowcount
# 提交事务
conn.commit()
print(f"Archived {deleted_count} old records (before {cutoff_str}).")
# 可选:重新缩小数据库文件大小
cursor.execute("VACUUM;")
print("VACUUM completed.")
except Exception as e:
print(f"An error occurred: {e}")
if conn:
conn.rollback()
finally:
if conn:
conn.close()
if __name__ == "__main__":
archive_old_records()
核心功能:跨数据库数据迁移
从生产数据库(pro.db)中抽取部分数据,插入到分析数据库(analysis.db)中。
#!/usr/bin/env python3
import sqlite3
PROD_DB = "pro.db"
ANALYSIS_DB = "analysis.db"
def migrate_sales_data():
conn_prod = None
conn_analysis = None
try:
conn_prod = sqlite3.connect(PROD_DB)
conn_analysis = sqlite3.connect(ANALYSIS_DB)
cursor_prod = conn_prod.cursor()
cursor_analysis = conn_analysis.cursor()
# 1. 从生产库获取昨天的新增销售记录
cursor_prod.execute("""
SELECT id, product_id, amount, created_at
FROM sales
WHERE created_at >= datetime('now', '-1 day')
""")
sales_data = cursor_prod.fetchall()
# 2. 确保分析库有对应的表
cursor_analysis.execute("""
CREATE TABLE IF NOT EXISTS sales_analysis (
id INTEGER PRIMARY KEY,
product_id INTEGER,
amount REAL,
created_at TEXT
)
""")
# 3. 插入数据(使用 executemany 提高效率)
if sales_data:
cursor_analysis.executemany("""
INSERT OR IGNORE INTO sales_analysis (id, product_id, amount, created_at)
VALUES (?, ?, ?, ?)
""", sales_data)
conn_analysis.commit()
print(f"Migrated {len(sales_data)} new sales records.")
else:
print("No new sales records to migrate.")
except Exception as e:
print(f"Migration failed: {e}")
if conn_analysis:
conn_analysis.rollback()
finally:
if conn_prod:
conn_prod.close()
if conn_analysis:
conn_analysis.close()
if __name__ == "__main__":
migrate_sales_data()
实用技巧与注意事项
-
安全性第一:
- 在修改数据的脚本中,一定要使用 事务(
conn.commit()和conn.rollback()或try...except)。 - 执行破坏性操作(如
DELETE或DROP)前,先执行备份。
- 在修改数据的脚本中,一定要使用 事务(
-
错误处理:
- Shell 脚本中使用
set -e可以让脚本在遇到任何错误时立即退出。 - Python 脚本务务必使用
try...except...finally来确保数据库连接被关闭。
- Shell 脚本中使用
-
WAL 模式(WAL = Write-Ahead Logging):
- 对于高并发的读写场景,可以在脚本开头执行
PRAGMA journal_mode=WAL;,这能显著提升性能。
- 对于高并发的读写场景,可以在脚本开头执行
-
外部监控与通知:
- 脚本执行结果可以通过邮件(
mail命令)、Slack Webhook(用curl)或生成日志文件来通知管理员。
- 脚本执行结果可以通过邮件(
-
并发处理:
- 脚本最好在没有人使用数据库的时候执行,比如凌晨。
- 如果必须在线运行,使用
.backup命令而不是直接复制文件,sqlite3 .backup命令能保证一致性。
| 需求 | 推荐方案 |
|---|---|
| 快速备份 / 简单维护 | Shell 脚本 + crontab |
| 跨平台 / 复杂业务逻辑 | Python + sqlite3 模块 |
| 数据库清理 / 数据归档 | Python 脚本(逻辑清晰,易调试) |
| 性能优化 / VACUUM | Shell 脚本(直接调用,简洁高效) |
| 跨数据库迁移 / 数据同步 | Python 脚本(处理复杂数据转换) |
实用脚本绝对能自动管理 SQLite 数据库,只需要一个文本编辑器、几分钟时间,你就能写出一个替代手动操作、稳定运行多年的自动化脚本。