ZetCode

Python sqlite3.Connection.iterdump 方法

上次修改时间:2025 年 4 月 15 日

这份全面的指南探讨了 Python 的 sqlite3.Connection.iterdump 方法,该方法生成 SQL 命令以重新创建数据库内容。我们将介绍基本用法、实际示例和常见模式。

基本定义

iterdump 方法返回一个迭代器,该迭代器将 SQL 命令作为字符串产生。执行这些命令可以重新创建数据库模式和数据。

主要特点:它产生有效的 SQL 语句,保留完整的数据库结构,并包含所有数据。它对于备份、迁移和数据库共享非常有用。

基本数据库转储

这是使用 iterdump 将数据库内容导出为 SQL 命令的最简单用法。

basic_dump.py
import sqlite3

# Create and populate a sample database
with sqlite3.connect('example.db') as conn:
    cursor = conn.cursor()
    cursor.execute('''CREATE TABLE users 
                     (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')
    cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30)")
    cursor.execute("INSERT INTO users (name, age) VALUES ('Bob', 25)")
    conn.commit()

# Dump the database contents
with sqlite3.connect('example.db') as conn:
    for line in conn.iterdump():
        print(line)

此示例创建一个简单的数据库,其中包含一个表和两个记录。然后,iterdump 方法生成 SQL 命令来重新创建它。

输出包括 CREATE TABLE 语句、INSERT 命令以及重建与原始数据库完全相同的数据库所需的其他 SQL。

将转储保存到文件

此示例演示如何将转储输出保存到文件中以进行备份。

save_to_file.py
import sqlite3

# Connect to database and save dump to file
with sqlite3.connect('example.db') as conn:
    with open('backup.sql', 'w') as f:
        for line in conn.iterdump():
            f.write(f"{line}\n")

print("Database backup saved to backup.sql")

该脚本将来自 iterdump 的每个 SQL 命令写入到文本文件。 此文件稍后可用于还原数据库。

对于中小型 SQLite 数据库,这是一种简单但有效的备份策略。 生成的文件是人类可读且可移植的。

从转储还原

此示例演示如何从使用 iterdump 创建的转储文件中还原数据库。

restore_from_dump.py
import sqlite3

# Create a new database from dump file
with sqlite3.connect('restored.db') as conn:
    cursor = conn.cursor()
    with open('backup.sql', 'r') as f:
        sql_script = f.read()
    cursor.executescript(sql_script)

print("Database restored from backup.sql")

该脚本从备份文件中读取 SQL 命令,并针对新数据库执行它们。 这会重新创建原始数据库结构和数据。

请注意,此处使用 executescript 是因为转储文件包含多个由分号分隔的 SQL 语句。

转储特定表

此示例演示如何仅从数据库中转储特定表。

specific_tables.py
import sqlite3

def dump_table(conn, table_name):
    cursor = conn.cursor()
    cursor.execute(f"SELECT * FROM {table_name}")
    rows = cursor.fetchall()
    
    # Get column names
    columns = [desc[0] for desc in cursor.description]
    
    # Generate CREATE TABLE statement
    cursor.execute(f"SELECT sql FROM sqlite_master WHERE type='table' AND name='{table_name}'")
    create_stmt = cursor.fetchone()[0]
    
    yield create_stmt + ";\n"
    
    # Generate INSERT statements
    for row in rows:
        values = ", ".join([f"'{str(v)}'" if v is not None else "NULL" for v in row])
        yield f"INSERT INTO {table_name} VALUES ({values});\n"

# Example usage
with sqlite3.connect('example.db') as conn:
    for line in dump_table(conn, 'users'):
        print(line)

此自定义函数模拟 iterdump,但仅适用于单个表。 它首先获取表架构,然后为所有行生成 INSERT 语句。

当您只需要备份或传输数据库中的特定表而不是整个内容时,此方法非常有用。

比较数据库

此示例演示如何通过比较两个数据库的转储输出来使用 iterdump 比较它们。

compare_databases.py
import sqlite3
import difflib

def get_dump_lines(conn):
    return list(conn.iterdump())

# Connect to both databases
with sqlite3.connect('db1.db') as conn1, sqlite3.connect('db2.db') as conn2:
    dump1 = get_dump_lines(conn1)
    dump2 = get_dump_lines(conn2)

# Generate diff
diff = difflib.unified_diff(dump1, dump2, fromfile='db1.db', tofile='db2.db')
print('\n'.join(diff))

该脚本从两个数据库生成转储,并使用 Python 的 difflib 来显示它们之间的差异。 这有助于识别架构或数据更改。

此技术对于调试、版本控制或验证不同环境之间的数据库迁移非常有价值。

内存数据库转储

此示例演示如何使用 iterdump 将内存数据库转储到文件中。

memory_dump.py
import sqlite3

# Create in-memory database
with sqlite3.connect(':memory:') as mem_conn:
    cursor = mem_conn.cursor()
    cursor.execute('''CREATE TABLE test (id INTEGER, data TEXT)''')
    cursor.execute("INSERT INTO test VALUES (1, 'Memory data')")
    mem_conn.commit()
    
    # Dump to file
    with open('memory_dump.sql', 'w') as f:
        for line in mem_conn.iterdump():
            f.write(f"{line}\n")

print("In-memory database saved to memory_dump.sql")

该脚本创建一个临时的内存数据库,用数据填充它,然后使用 iterdump 将其内容保存到文件中,然后它消失。

此模式对于保留临时数据库的状态或从动态生成的数据库创建模板非常有用。

使用进度跟踪进行转储

这个高级示例演示了如何在转储大型数据库时跟踪进度。

progress_tracking.py
import sqlite3
import sys

def dump_with_progress(conn, output_file):
    total = 0
    cursor = conn.cursor()
    
    # Count total tables for progress
    cursor.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table'")
    table_count = cursor.fetchone()[0]
    
    with open(output_file, 'w') as f:
        for i, line in enumerate(conn.iterdump()):
            f.write(f"{line}\n")
            
            # Update progress for each table
            if "CREATE TABLE" in line:
                progress = (i / table_count) * 100
                sys.stdout.write(f"\rProgress: {progress:.1f}%")
                sys.stdout.flush()
    
    print("\nDump complete")

# Example usage
with sqlite3.connect('large_db.db') as conn:
    dump_with_progress(conn, 'large_dump.sql')

此脚本通过添加进度跟踪来增强基本转储功能。 它首先统计表的数量,然后在转储每个表时更新进度。

对于非常大的数据库,此反馈对于估计剩余时间和确认该过程是否正常工作非常有价值。

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程