最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python備份SQLite數(shù)據(jù)庫的完整過程(附詳細(xì)代碼)

 更新時間:2026年02月10日 10:45:26   作者:weixin_pk138132  
SQLite數(shù)據(jù)庫的遷移是指將SQLite數(shù)據(jù)庫中的數(shù)據(jù)轉(zhuǎn)移到另一個數(shù)據(jù)庫系統(tǒng)(如MySQL、PostgreSQL等)中的過程,這篇文章主要介紹了使用Python備份SQLite數(shù)據(jù)庫的相關(guān)資料,需要的朋友可以參考下

1. 引言:為什么備份 SQLite 數(shù)據(jù)庫至關(guān)重要?

數(shù)據(jù)是任何應(yīng)用程序的核心資產(chǎn)。無論是個人項目還是商業(yè)應(yīng)用,數(shù)據(jù)的丟失都可能帶來災(zāi)難性后果。對于 SQLite 數(shù)據(jù)庫而言,備份更是不可或缺的實踐。

1.1 SQLite 數(shù)據(jù)庫的特點

  • 文件型數(shù)據(jù)庫:SQLite 數(shù)據(jù)庫以單個文件形式存儲在文件系統(tǒng)中(通常是 .db.sqlite 擴展名)。
  • 零配置、嵌入式:無需獨立的服務(wù)器進(jìn)程,直接嵌入到應(yīng)用程序中。
  • 高可用性:在應(yīng)用程序內(nèi)部直接訪問數(shù)據(jù),但在數(shù)據(jù)丟失時恢復(fù)復(fù)雜。

1.2 備份的常見場景與挑戰(zhàn)

  • 數(shù)據(jù)損壞:硬件故障、操作系統(tǒng)崩潰、程序錯誤等都可能導(dǎo)致數(shù)據(jù)庫文件損壞。
  • 意外刪除或修改:用戶或應(yīng)用程序的錯誤操作可能導(dǎo)致數(shù)據(jù)丟失或錯誤修改。
  • 遷移與升級:在數(shù)據(jù)庫遷移到新系統(tǒng)或進(jìn)行 schema 升級前,備份是安全保障。
  • 版本控制:為數(shù)據(jù)庫的不同狀態(tài)創(chuàng)建快照。

對于 SQLite 這種文件型數(shù)據(jù)庫,最簡單的備份方式似乎是直接復(fù)制文件。然而,如果數(shù)據(jù)庫在復(fù)制過程中處于活躍寫入狀態(tài),直接復(fù)制可能導(dǎo)致備份文件不一致或損壞。這就是 sqlite3.Connection.backup() 方法發(fā)揮作用的地方。

2. 核心方法:sqlite3.Connection.backup()

Python sqlite3 模塊提供了一個名為 backup() 的強大方法,它允許你在數(shù)據(jù)庫運行時進(jìn)行安全、一致的備份。

2.1backup()方法的工作原理

backup() 方法實現(xiàn)了 SQLite 數(shù)據(jù)庫的在線備份 API。它通過以下方式工作:

  1. 它在一個源數(shù)據(jù)庫連接和一個目標(biāo)數(shù)據(jù)庫連接之間進(jìn)行操作。
  2. 它會逐頁地將源數(shù)據(jù)庫的數(shù)據(jù)復(fù)制到目標(biāo)數(shù)據(jù)庫。
  3. 在復(fù)制過程中,它會確保數(shù)據(jù)的一致性,這意味著即使在備份期間源數(shù)據(jù)庫有寫入操作,備份文件也是一個在某個時間點上一致的快照。
  4. 這個過程是非阻塞的,源數(shù)據(jù)庫在備份期間可以繼續(xù)進(jìn)行讀寫操作。

2.2backup()的優(yōu)勢:原子性、一致性、非阻塞

  • 原子性:備份操作要么完全成功,要么不成功(如果失敗則不會留下?lián)p壞的備份文件)。
  • 一致性:生成的備份文件是源數(shù)據(jù)庫在備份開始時的一個完整、一致的副本,即使在備份過程中源數(shù)據(jù)庫被修改。
  • 非阻塞:源數(shù)據(jù)庫可以繼續(xù)接受讀寫請求,不會因為備份操作而被鎖定。

2.3 方法簽名與參數(shù)

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

  • target_connection: 目標(biāo)數(shù)據(jù)庫的 sqlite3.Connection 對象。備份的數(shù)據(jù)將寫入這個連接。
  • pages: 每次迭代復(fù)制的最大頁數(shù)。默認(rèn)為 -1,表示一次性復(fù)制所有剩余頁。對于大型數(shù)據(jù)庫,可以設(shè)置一個較小的正整數(shù)來分批復(fù)制,以便在備份過程中進(jìn)行其他操作或更新進(jìn)度。
  • progress: 一個可選的 callable 對象 (函數(shù)或方法),用于報告?zhèn)浞葸M(jìn)度。它會在每次復(fù)制一批頁后被調(diào)用。該 callable 接受三個整數(shù)參數(shù):
    1. status: 當(dāng)前已復(fù)制的頁數(shù)。
    2. remaining: 剩余未復(fù)制的頁數(shù)。
    3. total: 數(shù)據(jù)庫的總頁數(shù)。
  • name: 要備份的源數(shù)據(jù)庫的名稱。默認(rèn)為 'main'。這在處理附加數(shù)據(jù)庫 (attached databases) 時有用。
  • sleep: 在每次 pages 批次復(fù)制后,進(jìn)程休眠的時間(秒)。默認(rèn)為 0.250 秒。這可以減少備份操作對源數(shù)據(jù)庫性能的影響。

3. 分步實現(xiàn):使用backup()進(jìn)行備份

3.1準(zhǔn)備:創(chuàng)建示例源數(shù)據(jù)庫

首先,我們需要一個包含一些數(shù)據(jù)的 SQLite 數(shù)據(jù)庫文件作為源,以便進(jìn)行備份。

import sqlite3
import os

SOURCE_DB = "my_app.db"
BACKUP_DB = "my_app_backup.db"

def create_sample_db(db_filepath):
    """創(chuàng)建并填充一個示例SQLite數(shù)據(jù)庫。"""
    print(f"\n--- Creating sample database: {db_filepath} ---")
    conn = sqlite3.connect(db_filepath)
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            email TEXT UNIQUE,
            age INTEGER
        );
    ''')
    # 插入一些數(shù)據(jù),如果表為空
    cursor.execute("SELECT COUNT(*) FROM users;")
    if cursor.fetchone()[0] == 0:
        cursor.execute("INSERT INTO users (name, email, age) VALUES ('Alice', 'alice@example.com', 30);")
        cursor.execute("INSERT INTO users (name, email, age) VALUES ('Bob', 'bob@example.com', 25);")
        cursor.execute("INSERT INTO users (name, email, age) VALUES ('Charlie', 'charlie@example.com', 35);")
        conn.commit()
        print(f"  Inserted 3 sample users into '{db_filepath}'.")
    else:
        print(f"  '{db_filepath}' already contains data. Skipping insertion.")
    conn.close()

def cleanup_files(*filenames):
    """刪除指定的文件。"""
    print("\n--- Cleaning up files ---")
    for filename in filenames:
        if os.path.exists(filename):
            os.remove(filename)
            print(f"  Deleted file: {filename}")

3.2建立源數(shù)據(jù)庫連接

打開源數(shù)據(jù)庫文件,獲得一個 sqlite3.Connection 對象。

source_conn = sqlite3.connect(SOURCE_DB)

3.3建立目標(biāo)備份數(shù)據(jù)庫連接

打開目標(biāo)備份文件(如果文件不存在,sqlite3.connect() 會自動創(chuàng)建它)。

backup_conn = sqlite3.connect(BACKUP_DB)

3.4執(zhí)行備份操作

調(diào)用源連接對象的 backup() 方法,并傳入目標(biāo)連接。

try:
    source_conn.backup(backup_conn)
    print(f"Backup of '{SOURCE_DB}' to '{BACKUP_DB}' completed successfully.")
except sqlite3.Error as e:
    print(f"Error during backup: {e}")

3.5關(guān)閉連接與資源管理

無論備份成功與否,都應(yīng)該關(guān)閉兩個數(shù)據(jù)庫連接,釋放資源。

finally:
    if source_conn:
        source_conn.close()
    if backup_conn:
        backup_conn.close()

4. Python 代碼示例

import sqlite3
import os

# --- Configuration ---
SOURCE_DB = "my_application.db"
BACKUP_DB = "my_application_backup.db"

# --- Helper Functions (defined above, repeated for clarity) ---
def create_sample_db(db_filepath):
    """創(chuàng)建并填充一個示例SQLite數(shù)據(jù)庫。"""
    print(f"\n--- Creating sample database: {db_filepath} ---")
    conn = sqlite3.connect(db_filepath)
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            email TEXT UNIQUE,
            age INTEGER
        );
    ''')
    cursor.execute("SELECT COUNT(*) FROM users;")
    if cursor.fetchone()[0] == 0:
        cursor.execute("INSERT INTO users (name, email, age) VALUES ('Alice', 'alice@example.com', 30);")
        cursor.execute("INSERT INTO users (name, email, age) VALUES ('Bob', 'bob@example.com', 25);")
        cursor.execute("INSERT INTO users (name, email, age) VALUES ('Charlie', 'charlie@example.com', 35);")
        conn.commit()
        print(f"  Inserted 3 sample users into '{db_filepath}'.")
    else:
        print(f"  '{db_filepath}' already contains data. Skipping insertion.")
    conn.close()

def cleanup_files(*filenames):
    """刪除指定的文件。"""
    print("\n--- Cleaning up files ---")
    for filename in filenames:
        if os.path.exists(filename):
            os.remove(filename)
            print(f"  Deleted file: {filename}")

# --- Core Backup Function ---
def perform_backup(source_db_path, backup_db_path):
    """
    使用 sqlite3.Connection.backup() 方法備份 SQLite 數(shù)據(jù)庫。
    """
    print(f"\n--- Starting backup from '{source_db_path}' to '{backup_db_path}' ---")
    source_conn = None
    backup_conn = None
    try:
        source_conn = sqlite3.connect(source_db_path)
        backup_conn = sqlite3.connect(backup_db_path)
        
        # 執(zhí)行備份操作
        source_conn.backup(backup_conn)
        
        print(f"Backup of '{source_db_path}' to '{backup_db_path}' completed successfully.")
        return True
    except sqlite3.Error as e:
        print(f"Error during backup: {e}")
        return False
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        return False
    finally:
        if source_conn:
            source_conn.close()
        if backup_conn:
            backup_conn.close()

# --- Verification Function ---
def verify_backup(db_filepath):
    """驗證備份數(shù)據(jù)庫是否存在并包含數(shù)據(jù)。"""
    print(f"\n--- Verifying backup: {db_filepath} ---")
    if not os.path.exists(db_filepath):
        print(f"  Error: Backup file '{db_filepath}' does not exist.")
        return False

    conn = None
    try:
        conn = sqlite3.connect(db_filepath)
        cursor = conn.cursor()
        cursor.execute("SELECT COUNT(*) FROM users;")
        row_count = cursor.fetchone()[0]
        print(f"  Backup file '{db_filepath}' exists and contains {row_count} rows in 'users' table.")
        
        # 打印一些示例數(shù)據(jù)
        cursor.execute("SELECT id, name, email, age FROM users LIMIT 2;")
        sample_data = cursor.fetchall()
        print("  Sample data from backup:")
        for row in sample_data:
            print(f"    ID: {row[0]}, Name: {row[1]}, Email: {row[2]}, Age: {row[3]}")
        return True
    except sqlite3.Error as e:
        print(f"  Error accessing backup database '{db_filepath}': {e}")
        return False
    finally:
        if conn:
            conn.close()

# --- Main execution ---
# cleanup_files(SOURCE_DB, BACKUP_DB) # Clean up previous runs
# create_sample_db(SOURCE_DB)
# if perform_backup(SOURCE_DB, BACKUP_DB):
#     verify_backup(BACKUP_DB)
# cleanup_files(SOURCE_DB, BACKUP_DB) # Clean up after execution

5. 最佳實踐與注意事項

5.1錯誤處理 (try-except)

始終將備份操作包裝在 try...except sqlite3.Error 塊中,以捕獲可能發(fā)生的數(shù)據(jù)庫錯誤。如果使用 with 語句管理連接,它可以簡化資源釋放,但在 backup() 方法中,由于涉及兩個連接,手動 finally 塊確保關(guān)閉所有連接更為穩(wěn)妥。

5.2備份進(jìn)度監(jiān)控 (使用progress回調(diào))

對于大型數(shù)據(jù)庫,備份可能需要一段時間。提供一個 progress 回調(diào)函數(shù)可以向用戶顯示備份進(jìn)度。

def backup_progress(status, remaining, total):
    """
    備份進(jìn)度回調(diào)函數(shù)。
    :param status: 已復(fù)制的頁數(shù)。
    :param remaining: 剩余未復(fù)制的頁數(shù)。
    :param total: 數(shù)據(jù)庫的總頁數(shù)。
    """
    print(f"\r  Copied: {status} pages, Remaining: {remaining} pages, Total: {total} pages "
          f"({(status/total)*100:.2f}%)", end='')

# 在 perform_backup 函數(shù)中調(diào)用
# source_conn.backup(backup_conn, progress=backup_progress)
# print() # 備份完成后換行

5.3文件路徑管理

  • 唯一文件名:為備份文件添加時間戳或版本號,以防止覆蓋,并能夠回溯到不同時間點的備份。例如 my_app_backup_2023-10-27_10-30-00.db。
  • 備份目錄:將所有備份存儲在一個專門的備份目錄中,方便管理和清理。

5.4替代方案:簡單的文件復(fù)制 (shutil.copyfile)

如果你確定在備份時數(shù)據(jù)庫沒有被任何進(jìn)程寫入,或者數(shù)據(jù)庫是一個只讀文件,那么直接使用 shutil.copyfile() 是一種簡單快速的方法。

import shutil

def simple_file_copy_backup(source_path, backup_path):
    """
    簡單的文件復(fù)制備份,僅在源數(shù)據(jù)庫未被寫入時安全。
    """
    print(f"\n--- Performing simple file copy backup from '{source_path}' to '{backup_path}' ---")
    if not os.path.exists(source_path):
        print(f"  Error: Source database '{source_path}' does not exist.")
        return False
    try:
        shutil.copyfile(source_path, backup_path)
        print(f"  Successfully copied '{source_path}' to '{backup_path}'.")
        return True
    except Exception as e:
        print(f"  Error during file copy: {e}")
        return False

# --- 嚴(yán)重警告 ---
# 僅當(dāng)確定源數(shù)據(jù)庫在復(fù)制期間不會有任何寫入操作時才使用此方法。
# 否則,你可能會得到一個損壞或不一致的備份文件。
# 對于正在使用的數(shù)據(jù)庫,始終優(yōu)先使用 sqlite3.Connection.backup()。

5.5備份壓縮(zipfile,shutil.make_archive)

SQLite 數(shù)據(jù)庫文件可能很大。為了節(jié)省存儲空間和方便傳輸,可以考慮對備份文件進(jìn)行壓縮。

import zipfile

def compress_backup(db_filepath, zip_filepath):
    """將數(shù)據(jù)庫文件壓縮成zip文件。"""
    print(f"\n--- Compressing '{db_filepath}' to '{zip_filepath}' ---")
    try:
        with zipfile.ZipFile(zip_filepath, 'w', zipfile.ZIP_DEFLATED) as zf:
            zf.write(db_filepath, os.path.basename(db_filepath))
        print(f"  Successfully compressed '{db_filepath}' to '{zip_filepath}'.")
        return True
    except Exception as e:
        print(f"  Error compressing backup: {e}")
        return False

# Example usage:
# if perform_backup(SOURCE_DB, BACKUP_DB):
#     compress_backup(BACKUP_DB, BACKUP_DB + ".zip")

5.6自動化與調(diào)度

在生產(chǎn)環(huán)境中,備份通常是自動化任務(wù)。你可以使用:

  • Linux/macOS: cron 任務(wù)調(diào)度器來定時執(zhí)行 Python 備份腳本。
  • Windows: 任務(wù)計劃程序 (Task Scheduler) 來定時執(zhí)行 Python 備份腳本。

5.7存儲位置與恢復(fù)策略

  • 異地存儲:將備份文件存儲在與源數(shù)據(jù)庫不同的物理位置(例如,網(wǎng)絡(luò)共享、云存儲、外部硬盤),以防止整個系統(tǒng)故障導(dǎo)致數(shù)據(jù)丟失。
  • 多個備份版本:保留多個時間點的備份,以便在需要時可以選擇恢復(fù)到某個特定的歷史狀態(tài)。
  • 測試恢復(fù):定期測試備份文件的可恢復(fù)性,確保備份有效。

5.8從備份恢復(fù)

恢復(fù)通常只是將備份文件復(fù)制回原始數(shù)據(jù)庫的位置。但在復(fù)制之前,請確保原始數(shù)據(jù)庫文件被關(guān)閉或刪除,并且備份文件是正確的。

def restore_from_backup(backup_db_path, target_db_path):
    """
    從備份文件恢復(fù)數(shù)據(jù)庫。
    警告:這將覆蓋目標(biāo)路徑的現(xiàn)有數(shù)據(jù)庫!
    """
    print(f"\n--- Restoring from '{backup_db_path}' to '{target_db_path}' ---")
    if not os.path.exists(backup_db_path):
        print(f"  Error: Backup file '{backup_db_path}' does not exist.")
        return False
    try:
        # 確保目標(biāo)數(shù)據(jù)庫連接已關(guān)閉
        if os.path.exists(target_db_path):
            os.remove(target_db_path) # 刪除舊的(或損壞的)數(shù)據(jù)庫
            print(f"  Deleted existing database at '{target_db_path}'.")
        shutil.copyfile(backup_db_path, target_db_path)
        print(f"  Successfully restored '{backup_db_path}' to '{target_db_path}'.")
        return True
    except Exception as e:
        print(f"  Error during restoration: {e}")
        return False

6. 綜合代碼示例:包含進(jìn)度監(jiān)控和驗證

import sqlite3
import os
import shutil # For file copy operations and cleanup
import datetime # For timestamping backup files

# --- Configuration ---
SOURCE_DB = "production_app.db"
BACKUP_DIR = "backups" # Directory to store backups
ZIP_DIR = "compressed_backups" # Directory to store compressed backups

# --- 1. Helper Functions ---
def create_sample_db(db_filepath):
    """Creates and populates a sample SQLite database."""
    print(f"\n--- Creating sample database: {db_filepath} ---")
    conn = None
    try:
        conn = sqlite3.connect(db_filepath)
        cursor = conn.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS inventory (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                item_name TEXT NOT NULL,
                quantity INTEGER DEFAULT 0,
                last_updated TEXT
            );
        ''')
        cursor.execute("SELECT COUNT(*) FROM inventory;")
        if cursor.fetchone()[0] == 0:
            cursor.execute("INSERT INTO inventory (item_name, quantity, last_updated) VALUES ('Laptop', 150, '2023-10-26 10:00:00');")
            cursor.execute("INSERT INTO inventory (item_name, quantity, last_updated) VALUES ('Monitor', 200, '2023-10-26 11:30:00');")
            cursor.execute("INSERT INTO inventory (item_name, quantity, last_updated) VALUES ('Keyboard', 300, '2023-10-26 12:00:00');")
            conn.commit()
            print(f"  Inserted 3 sample items into '{db_filepath}'.")
        else:
            print(f"  '{db_filepath}' already contains data. Skipping insertion.")
    except sqlite3.Error as e:
        print(f"  Database error during sample DB creation: {e}")
    finally:
        if conn:
            conn.close()

def cleanup_dirs(*dirs):
    """Deletes directories and their contents."""
    print("\n--- Cleaning up directories ---")
    for dir_path in dirs:
        if os.path.exists(dir_path):
            shutil.rmtree(dir_path)
            print(f"  Deleted directory: {dir_path}")

def cleanup_files(*filenames):
    """Deletes specified files."""
    for filename in filenames:
        if os.path.exists(filename):
            os.remove(filename)
            print(f"  Deleted file: {filename}")

def get_backup_filename(base_name, timestamp=True, extension=".db"):
    """生成帶時間戳的備份文件名。"""
    if timestamp:
        current_time = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        return f"{base_name}_{current_time}{extension}"
    return f"{base_name}{extension}"

# --- 2. Backup Progress Callback ---
def backup_progress_callback(status, remaining, total):
    """Prints backup progress to the console."""
    percentage = (status / total) * 100 if total > 0 else 0
    print(f"\r  Progress: {status}/{total} pages ({percentage:.2f}%) "
          f"Remaining: {remaining} pages", end='', flush=True)

# --- 3. Core Backup Function ---
def perform_db_backup(source_db_path, backup_dir_path):
    """
    使用 sqlite3.Connection.backup() 方法備份 SQLite 數(shù)據(jù)庫,并包含進(jìn)度監(jiān)控。
    備份文件將存儲在 backup_dir_path 目錄下,并帶有時間戳。
    """
    if not os.path.exists(backup_dir_path):
        os.makedirs(backup_dir_path)
        print(f"  Created backup directory: {backup_dir_path}")

    base_name = os.path.basename(source_db_path).replace(".db", "")
    backup_filename = get_backup_filename(base_name)
    target_backup_path = os.path.join(backup_dir_path, backup_filename)
    
    print(f"\n--- Starting online backup from '{source_db_path}' to '{target_backup_path}' ---")
    source_conn = None
    backup_conn = None
    try:
        source_conn = sqlite3.connect(source_db_path)
        backup_conn = sqlite3.connect(target_backup_path)
        
        # 執(zhí)行備份操作,包含進(jìn)度回調(diào)
        source_conn.backup(backup_conn, pages=1, progress=backup_progress_callback, sleep=0.05) # Small pages for visible progress
        
        print("\nBackup completed successfully.")
        return target_backup_path
    except sqlite3.Error as e:
        print(f"\nError during backup: {e}")
        if os.path.exists(target_backup_path):
            os.remove(target_backup_path) # Clean up partial backup on error
            print(f"  Removed incomplete backup file: {target_backup_path}")
        return None
    except Exception as e:
        print(f"\nAn unexpected error occurred during backup: {e}")
        return None
    finally:
        if source_conn:
            source_conn.close()
        if backup_conn:
            backup_conn.close()

# --- 4. Verification Function ---
def verify_db_backup(db_filepath):
    """Verifies the backup database exists and contains data."""
    print(f"\n--- Verifying backup: {db_filepath} ---")
    if not os.path.exists(db_filepath):
        print(f"  Error: Backup file '{db_filepath}' does not exist.")
        return False

    conn = None
    try:
        conn = sqlite3.connect(db_filepath)
        cursor = conn.cursor()
        cursor.execute("SELECT COUNT(*) FROM inventory;")
        row_count = cursor.fetchone()[0]
        print(f"  Backup file '{db_filepath}' exists and contains {row_count} rows in 'inventory' table.")
        
        cursor.execute("SELECT id, item_name, quantity FROM inventory LIMIT 2;")
        sample_data = cursor.fetchall()
        print("  Sample data from backup:")
        for row in sample_data:
            print(f"    ID: {row[0]}, Item: {row[1]}, Quantity: {row[2]}")
        return True
    except sqlite3.Error as e:
        print(f"  Error accessing backup database '{db_filepath}': {e}")
        return False
    except Exception as e:
        print(f"  An unexpected error occurred during verification: {e}")
        return False
    finally:
        if conn:
            conn.close()

# --- 5. Compression Function ---
def compress_db_backup(db_filepath, compressed_dir_path):
    """Compresses a database file into a .zip archive."""
    if not os.path.exists(compressed_dir_path):
        os.makedirs(compressed_dir_path)
        print(f"  Created compressed backup directory: {compressed_dir_path}")

    zip_filename = os.path.basename(db_filepath) + ".zip"
    target_zip_path = os.path.join(compressed_dir_path, zip_filename)
    
    print(f"\n--- Compressing '{db_filepath}' to '{target_zip_path}' ---")
    try:
        with zipfile.ZipFile(target_zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
            zf.write(db_filepath, os.path.basename(db_filepath)) # Write with just filename inside zip
        print(f"  Successfully compressed '{db_filepath}' to '{target_zip_path}'.")
        return target_zip_path
    except Exception as e:
        print(f"  Error compressing backup: {e}")
        return None

# --- Main Program Execution ---
def main():
    cleanup_dirs(BACKUP_DIR, ZIP_DIR)
    cleanup_files(SOURCE_DB) # Ensure source DB is clean if it was left from previous run

    create_sample_db(SOURCE_DB) # Create the source database with some data

    # Perform backup using sqlite3.Connection.backup()
    backup_file_path = perform_db_backup(SOURCE_DB, BACKUP_DIR)
    
    if backup_file_path:
        verify_db_backup(backup_file_path) # Verify the created backup
        
        # Optionally, compress the backup file
        compressed_file_path = compress_db_backup(backup_file_path, ZIP_DIR)
        if compressed_file_path:
            print(f"\nCompressed backup available at: {compressed_file_path}")
            
    print("\n--- Program finished ---")
    # cleanup_dirs(BACKUP_DIR, ZIP_DIR) # Uncomment to delete backup files after run
    # cleanup_files(SOURCE_DB) # Uncomment to delete source DB after run

if __name__ == "__main__":
    main()

7. 總結(jié)

為您詳盡解析了在 Python 中使用 sqlite3 模塊備份 SQLite 數(shù)據(jù)庫的方法。

核心要點回顧:

  • sqlite3.Connection.backup() 是在數(shù)據(jù)庫活躍時進(jìn)行安全、一致備份的最佳實踐,它保證了原子性和非阻塞性。
  • 進(jìn)度監(jiān)控:使用 progress 回調(diào)函數(shù)可以為大型數(shù)據(jù)庫備份提供用戶反饋。
  • 錯誤處理:始終捕獲 sqlite3.Error 以確保程序的健壯性。
  • 文件名和目錄管理:為備份文件添加時間戳,并組織到專門的備份目錄中,便于管理。
  • 文件復(fù)制 (shutil.copyfile) 僅適用于確定數(shù)據(jù)庫未被寫入的場景,否則存在數(shù)據(jù)損壞風(fēng)險。
  • 壓縮:使用 zipfile 等模塊可以有效減小備份文件大小。
  • 自動化和異地存儲:考慮將備份過程自動化,并將備份文件存儲在安全、獨立的位置。

通過掌握這些方法和最佳實踐,您將能夠構(gòu)建一個可靠的備份策略,有效保護(hù)您的 SQLite 數(shù)據(jù)庫數(shù)據(jù)免受意外丟失。

到此這篇關(guān)于使用Python備份SQLite數(shù)據(jù)庫的文章就介紹到這了,更多相關(guān)Python備份SQLite數(shù)據(jù)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

长丰县| 绥化市| 克什克腾旗| 丰顺县| 图木舒克市| 巴林左旗| 蓝山县| 望城县| 平江县| 晋江市| 昌邑市| 灵璧县| 井冈山市| 呼玛县| 搜索| 拉萨市| 罗甸县| 石阡县| 修水县| 淳安县| 吉木萨尔县| 冕宁县| 射阳县| 凤庆县| 四平市| 景洪市| 土默特左旗| 水富县| 辽源市| 古蔺县| 白沙| 崇阳县| 林周县| 阜城县| 新郑市| 临洮县| 方城县| 盈江县| 都兰县| 赞皇县| 铁力市|