Featured image of post SQLite3

SQLite3

简要介绍python内置数据库SQLite3的一些使用方法

打开数据库

使用SQLite3创建数据的连接,当数据库文件存在则连接对象直接打开数据库文件,不存在则自动创建数据库文件。连接对象可以是硬盘上面的数据库文件,也可以是建立在内存(memory)中的,在内存中的数据库执行完任何操作后,都不需要提交事务的(commit)

SQLite3的connect方法返回con对象,即数据库连接对象,提供如下方法:

方法 描述
.cursor() 创建一个游标对象
.commit() 处理事务提交
.rollback() 处理事务回滚
.close() 关闭一个数据库连接

创建数据库

在硬盘上建立数据库

1
con=sqlite3.connect("E:\Test.db")

路径中单斜杠和双斜杠不做区分,且数据库的名称不区分大小写,即E:\Test.dbE:\\Test.dbE:\TEST.db 均相同。 但需要注意的是: E:\test.db 会报错,因为编译器会识别到 \t 为制表符,因此认为路径不对。

1
con=sqlite3.connect("Test.db")

不加全路径则在项目文件下创建数据库

在内存上创建数据库

1
con=sqlite3.connect("memory")

两者差别

追求极致速度和临时性就选内存数据库;需要数据持久保存、大容量或共享访问则选文件数据库。

混合模式可以兼顾两者优点:你可以将整个文件数据库附加 (ATTACH) 到内存数据库中进行高速操作,处理完成后再将结果写回磁盘文件。这适合“热数据”需要内存加速,而“冷数据”需要持久化的复杂场景

创建游标

游标对象是数据库管理系统提供的一种数据访问机制,它就像一个指向查询结果集的指针,允许你逐行处理数据,而不是一次性操作整个结果集

方法 描述
.execute() 用来执行SQL语句
.executemany() 批量执行同一条SQL语句
.close() 用来关闭游标
.fetchone() 从查询结果中获取下一行数据
.fetchmany() 从结果中取出多条记录
.fetchall() 取出所有剩余记录
.scroll() 用于游标滚动

执行SQL语句

创建表

1
cur.execute("CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY,name TEXT,age INTEGER)")

新增数据

方法一

1
2
data = "5,'leon',22"
cur.execute('INSERT INTO test VALUES (%s)'%data)

方法二

1
cur.execute("INSERT INTO test values(?,?,?)",(6,"zgq",20))

方法三

1
cur.executemany('INSERT INTO test VALUES (?,?,?)',[(3,'name3',19),(4,'name4',26)])

更新数据

方法一

1
cur.execute("UPDATE test SET name=? WHERE id=?",("nihao",1))

方法二

1
cur.execute("UPDATE test SET name='haha' WHERE id=1")

删除数据

方法一

1
n=cur.execute("DELETE FROM test WHERE id=?",(1,))

方法二

1
n=cur.execute("DELETE FROM test WHERE id=1")

返回的n为被删除的对象

查询数据

1
cur.execute("SELECT * FROM test")

查询结果存储在游标对象cur中,可以使用对象的方法进行访问,例如遍历或使用.fetchone()等方法

删除表

1
cur.execute("DROP TABLE Test ")

事务回滚或提交

提交

1
con.commit()

回滚

1
con.rollback()

关闭数据库和游标

1
2
cur.close()
con.close()

一定要先关闭游标,再关闭数据库连接,否则会报错

案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import sqlite3

# 连接到内存数据库并创建游标对象
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()

print("=== 1. 使用 .execute() 创建表并插入单条数据 ===\n")

# .execute(): 执行一条SQL语句来创建表
create_table_sql = """
CREATE IF NOT EXISTS EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    age INTEGER
)
"""
cursor.execute(create_table_sql)

# .execute(): 执行一条INSERT语句插入单条数据
insert_sql = "INSERT INTO users (name, age) VALUES (?, ?)"
cursor.execute(insert_sql, ('Alice', 25))
print(f"插入单条数据,受影响的行数: {cursor.rowcount}")

print("\n=== 2. 使用 .executemany() 批量插入数据 ===\n")

# .executemany(): 执行同一条SQL语句,但传入多组参数
users_data = [
    ('Bob', 30),
    ('Charlie', 35),
    ('Diana', 28),
    ('Evan', 40)
]
cursor.executemany(insert_sql, users_data)
print(f"批量插入数据,受影响的行数: {cursor.rowcount}")

# 提交事务,使插入的数据生效
conn.commit()

print("\n=== 3. 使用 .fetch*() 系列方法查询数据 ===\n")

# .execute(): 执行查询语句
cursor.execute("SELECT * FROM users ORDER BY id")

print("--- 使用 .fetchone() 逐条获取 ---")
# .fetchone(): 获取结果集中的下一行
first_row = cursor.fetchone()
print(f"第一条记录: {first_row}")

second_row = cursor.fetchone()
print(f"第二条记录: {second_row}")

print("\n--- 使用 .fetchmany() 获取指定数量的记录 ---")
# .fetchmany(size): 获取指定数量的行
# 注意:此时游标指向第三条记录
next_few_rows = cursor.fetchmany(2) # 获取接下来的2条记录
print(f"接下来的两条记录: {next_few_rows}")

print("\n--- 使用 .fetchall() 获取所有剩余记录 ---")
# .fetchall(): 获取结果集中所有剩余的行
remaining_rows = cursor.fetchall()
print(f"所有剩余记录: {remaining_rows}")

# 再次执行查询,让游标回到结果集开头
cursor.execute("SELECT * FROM users ORDER BY id")
all_rows = cursor.fetchall()
print(f"\n--- 使用 .fetchall() 获取全部记录 ---")
print(f"全部记录: {all_rows}")

print("\n=== 4. 使用 .scroll() 滚动游标 ===\n")

# 为了演示.scroll(),我们重新执行查询
cursor.execute("SELECT * FROM users ORDER BY id")

# .scroll(value, mode='relative'): 相对当前位置移动游标
cursor.fetchone() # 先读取第一条,游标到第二条
print(f"读取第一条后,当前游标位置在第二条")

# 相对移动:从当前位置向后移动2条记录
cursor.scroll(2, mode='relative')
row_after_scroll = cursor.fetchone()
print(f"相对当前位置向后滚动2条后,读取的记录是: {row_after_scroll}") # 应该是第5条

# .scroll(value, mode='absolute'): 移动到结果集的绝对位置
cursor.scroll(0, mode='absolute') # 滚动到开头(第0条,但索引从0开始)
first_row_again = cursor.fetchone()
print(f"绝对滚动到开头后,读取的记录是: {first_row_again}") # 应该是第1条

print("\n=== 5. 使用 .close() 关闭游标 ===\n")

# .close(): 关闭游标,释放资源
print(f"关闭前,游标状态: {not cursor.closed}") # False 表示未关闭
cursor.close()
print(f"关闭后,游标状态: {cursor.closed}") # True 表示已关闭

# 关闭数据库连接
conn.close()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
=== 1. 使用 .execute() 创建表并插入单条数据 ===

插入单条数据,受影响的行数: 1

=== 2. 使用 .executemany() 批量插入数据 ===

批量插入数据,受影响的行数: 4

=== 3. 使用 .fetch*() 系列方法查询数据 ===

--- 使用 .fetchone() 逐条获取 ---
第一条记录: (1, 'Alice', 25)
第二条记录: (2, 'Bob', 30)

--- 使用 .fetchmany() 获取指定数量的记录 ---
接下来的两条记录: [(3, 'Charlie', 35), (4, 'Diana', 28)]

--- 使用 .fetchall() 获取所有剩余记录 ---
所有剩余记录: [(5, 'Evan', 40)]

--- 使用 .fetchall() 获取全部记录 ---
全部记录: [(1, 'Alice', 25), (2, 'Bob', 30), (3, 'Charlie', 35), (4, 'Diana', 28), (5, 'Evan', 40)]

=== 4. 使用 .scroll() 滚动游标 ===

读取第一条后,当前游标位置在第二条
相对当前位置向后滚动2条后,读取的记录是: (5, 'Evan', 40)
绝对滚动到开头后,读取的记录是: (1, 'Alice', 25)

=== 5. 使用 .close() 关闭游标 ===

关闭前,游标状态: True
关闭后,游标状态: False
恍如昨日,嗤笑今朝
使用 Hugo 构建
主题 StackJimmy 设计