杰瑞科技汇

Python SQLite 插入数据怎么操作?

连接到数据库

在插入数据之前,你必须首先连接到 SQLite 数据库,如果数据库文件不存在,SQLite 会自动创建它。

import sqlite3
# 数据库文件名
db_file = 'my_database.db'
# 连接到数据库 (如果不存在,则会创建)
# 使用 'with' 语句可以确保连接在使用完毕后自动关闭
try:
    conn = sqlite3.connect(db_file)
    print(f"成功连接到数据库: {db_file}")
    # 创建一个游标对象,用于执行 SQL 语句
    cursor = conn.cursor()
except sqlite3.Error as e:
    print(f"连接数据库时出错: {e}")

创建表(如果不存在)

在插入数据之前,通常需要有一个表来存储数据,让我们创建一个简单的 users 表。

# 创建一个表的 SQL 语句
create_table_sql = """
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT NOT NULL UNIQUE,
    age INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
"""
try:
    # 执行 SQL 语句
    cursor.execute(create_table_sql)
    print("表 'users' 创建成功或已存在。")
    # 提交事务
    conn.commit()
except sqlite3.Error as e:
    print(f"创建表时出错: {e}")
    # 发生错误时回滚
    conn.rollback()

说明:

  • CREATE TABLE IF NOT EXISTS: 如果表不存在才创建,避免重复创建导致错误。
  • id INTEGER PRIMARY KEY AUTOINCREMENT: id 是主键,并且会自动递增。
  • name TEXT NOT NULL: name 列不能为空。
  • email TEXT NOT NULL UNIQUE: email 列不能为空,并且值必须唯一。
  • created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP: 创建记录时,如果没有提供值,则自动设置为当前时间。

插入数据

插入数据有几种方式,强烈推荐使用参数化查询来防止 SQL 注入。

单条数据插入(推荐)

这是最安全、最常用的方式,使用 作为占位符,然后将数据作为元组传给 execute() 方法。

# 要插入的数据
new_user = ('Alice', 'alice@example.com', 30)
# 插入数据的 SQL 语句,使用 ? 作为占位符
insert_sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?);"
try:
    # 执行 SQL 语句
    cursor.execute(insert_sql, new_user)
    # 提交事务,将更改保存到数据库
    conn.commit()
    print(f"成功插入数据: {cursor.lastrowid}") # cursor.lastrowid 可以获取最后插入行的ID
except sqlite3.Error as e:
    print(f"插入数据时出错: {e}")
    conn.rollback()

使用字典(更具可读性)

如果你更喜欢使用列名而不是位置,可以传递一个字典给 execute() 方法,这需要 SQL 语句使用 key 作为占位符。

# 要插入的数据(使用字典)
new_user_dict = {'name': 'Bob', 'email': 'bob@example.com', 'age': 25}
# 插入数据的 SQL 语句,使用 :key 作为占位符
insert_sql_dict = "INSERT INTO users (name, email, age) VALUES (:name, :email, :age);"
try:
    cursor.execute(insert_sql_dict, new_user_dict)
    conn.commit()
    print(f"成功插入数据: {cursor.lastrowid}")
except sqlite3.Error as e:
    print(f"插入数据时出错: {e}")
    conn.rollback()

批量插入数据

当需要插入大量数据时,逐条调用 execute() 会非常慢,这时应该使用 executemany() 方法,它比循环调用 execute() 效率高出许多。

# 要插入的多条数据(列表的列表或列表的元组)
many_users = [
    ('Charlie', 'charlie@example.com', 35),
    ('David', 'david@example.com', 28),
    ('Eve', 'eve@example.com', 22)
]
# 插入单条数据的 SQL 语句模板
insert_sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?);"
try:
    # executemany() 会遍历 many_users 列表,并对每个元组执行一次 execute()
    cursor.executemany(insert_sql, many_users)
    conn.commit()
    print(f"成功批量插入 {cursor.rowcount} 条数据。")
except sqlite3.Error as e:
    print(f"批量插入数据时出错: {e}")
    conn.rollback()

完整示例与最佳实践

下面是一个完整的、结构化的示例,包含了连接、创建表、插入数据和查询数据的全过程,它强调了使用 with 语句管理连接始终使用参数化查询的重要性。

import sqlite3
from datetime import datetime
def setup_database(db_name='company.db'):
    """连接到数据库并设置表结构"""
    try:
        # 使用 with 语句,连接会在代码块执行完毕后自动关闭
        with sqlite3.connect(db_name) as conn:
            cursor = conn.cursor()
            # 创建员工表
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS employees (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    position TEXT NOT NULL,
                    salary REAL,
                    hire_date DATE
                );
            """)
            conn.commit()
            print(f"数据库 '{db_name}' 设置完成。")
    except sqlite3.Error as e:
        print(f"设置数据库时出错: {e}")
def add_employee(db_name, name, position, salary, hire_date):
    """添加一名新员工"""
    try:
        with sqlite3.connect(db_name) as conn:
            cursor = conn.cursor()
            # 使用参数化查询,防止 SQL 注入!
            sql = "INSERT INTO employees (name, position, salary, hire_date) VALUES (?, ?, ?, ?);"
            employee_data = (name, position, salary, hire_date)
            cursor.execute(sql, employee_data)
            conn.commit()
            print(f"成功添加员工: {name}, ID: {cursor.lastrowid}")
    except sqlite3.Error as e:
        print(f"添加员工失败: {e}")
def add_employees_bulk(db_name, employees_list):
    """批量添加员工"""
    try:
        with sqlite3.connect(db_name) as conn:
            cursor = conn.cursor()
            sql = "INSERT INTO employees (name, position, salary, hire_date) VALUES (?, ?, ?, ?);"
            # executemany 是批量插入的高效方式
            cursor.executemany(sql, employees_list)
            conn.commit()
            print(f"成功批量添加 {cursor.rowcount} 名员工。")
    except sqlite3.Error as e:
        print(f"批量添加员工失败: {e}")
def get_all_employees(db_name):
    """获取所有员工信息"""
    try:
        with sqlite3.connect(db_name) as conn:
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM employees;")
            # fetchall() 获取所有结果
            employees = cursor.fetchall()
            print("\n--- 所有员工列表 ---")
            if not employees:
                print("暂无员工数据。")
            else:
                for emp in employees:
                    print(f"ID: {emp[0]}, 姓名: {emp[1]}, 职位: {emp[2]}, 薪资: {emp[3]}, 入职日期: {emp[4]}")
    except sqlite3.Error as e:
        print(f"查询员工数据失败: {e}")
# --- 主程序 ---
if __name__ == "__main__":
    DB_FILE = 'company.db'
    # 1. 初始化数据库
    setup_database(DB_FILE)
    # 2. 添加单个员工
    add_employee(DB_FILE, '张三', '软件工程师', 12000.00, '2025-01-15')
    add_employee(DB_FILE, '李四', '产品经理', 15000.00, '2025-11-20')
    # 3. 批量添加员工
    new_employees = [
        ('王五', '数据分析师', 10000.00, '2025-03-10'),
        ('赵六', 'UI设计师', 9000.00, '2025-05-01'),
        ('钱七', '测试工程师', 8500.00, '2025-02-28')
    ]
    add_employees_bulk(DB_FILE, new_employees)
    # 4. 查询并打印所有员工
    get_all_employees(DB_FILE)

总结与关键点

  1. 连接与关闭:使用 sqlite3.connect() 连接数据库,最佳实践是使用 with 语句,它能自动处理连接的关闭和事务的提交/回滚。
  2. 游标:通过 conn.cursor() 获取游标对象,所有 SQL 操作都通过游标完成。
  3. 执行与提交cursor.execute() 用于执行单条 SQL,cursor.executemany() 用于批量执行,执行后必须调用 conn.commit() 才能将更改永久保存到数据库。
  4. 事务:SQLite 默认是事务性的,从你开始执行 SQL 到你调用 commit()rollback(),这整个过程就是一个事务,如果中途出错,调用 rollback() 可以撤销所有未提交的更改。
  5. 防止 SQL 注入(最重要!)永远不要使用字符串拼接来构建 SQL 语句,这会导致严重的安全漏洞,始终使用参数化查询,即 或 key 占位符。
  6. 获取结果:插入后,可以使用 cursor.lastrowid 获取新插入行的 ID,查询时,使用 cursor.fetchone() (一条)、cursor.fetchall() (所有) 或 cursor.fetchmany(size) (多条) 来获取结果集。
分享:
扫描分享到社交APP
上一篇
下一篇