实用脚本能自动管理SQLite数据库吗?

wen 实用脚本 6

本文目录导读:

实用脚本能自动管理SQLite数据库吗?

  1. 场景一:使用 Shell 脚本(Linux/macOS 环境)
  2. 场景二:使用 Python 脚本(跨平台,功能更强大)
  3. 实用技巧与注意事项

完全可以,而且用脚本自动管理 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 数据库在频繁删除和插入后,文件大小可能不会自动缩小,需要定期执行 VACUUMREINDEX

脚本文件: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()

实用技巧与注意事项

  1. 安全性第一

    • 在修改数据的脚本中,一定要使用 事务conn.commit()conn.rollback()try...except)。
    • 执行破坏性操作(如 DELETEDROP)前,先执行备份
  2. 错误处理

    • Shell 脚本中使用 set -e 可以让脚本在遇到任何错误时立即退出。
    • Python 脚本务务必使用 try...except...finally 来确保数据库连接被关闭。
  3. WAL 模式(WAL = Write-Ahead Logging)

    • 对于高并发的读写场景,可以在脚本开头执行 PRAGMA journal_mode=WAL;,这能显著提升性能。
  4. 外部监控与通知

    • 脚本执行结果可以通过邮件(mail 命令)、Slack Webhook(用 curl)或生成日志文件来通知管理员。
  5. 并发处理

    • 脚本最好在没有人使用数据库的时候执行,比如凌晨。
    • 如果必须在线运行,使用 .backup 命令而不是直接复制文件,sqlite3 .backup 命令能保证一致性。
需求 推荐方案
快速备份 / 简单维护 Shell 脚本 + crontab
跨平台 / 复杂业务逻辑 Python + sqlite3 模块
数据库清理 / 数据归档 Python 脚本(逻辑清晰,易调试)
性能优化 / VACUUM Shell 脚本(直接调用,简洁高效)
跨数据库迁移 / 数据同步 Python 脚本(处理复杂数据转换)

实用脚本绝对能自动管理 SQLite 数据库,只需要一个文本编辑器、几分钟时间,你就能写出一个替代手动操作、稳定运行多年的自动化脚本。

抱歉,评论功能暂时关闭!