Python3: sqlite3 模块 - SQLite3 数据库操作

梦里梦外; 2021-09-21 23:08 757阅读 0赞

本文链接: https://blog.csdn.net/xietansheng/article/details/115559160

Python3 学习笔记(目录)

Python 官方文档:

  • sqlite3 模块: sqlite3 — DB-API 2.0 interface for SQLite databases

1. 主要对象

sqlite3 模块主要对象:

  • 数据库连接对象: sqlite3.Connection
  • 游标对象: sqlite3.Cursor

使用sqlite3模块,先创建Connection数据库连接对象,再创建Cursor游标对象,然后调用cursor.execute()方法执行 SQL 语句。

1.1 Connection

连接数据库方法: sqlite3.connect(database, …)

  1. # 连接 SQLite 数据,
  2. # database 是准备打开的数据库文件路径,
  3. # database 也可以传 ":memory:" 在内存中打开一个数据库。
  4. # 默认返回 Connection 对象
  5. sqlite3.connect(database[, timeout, detect_types,
  6. isolation_level, check_same_thread,
  7. factory, cached_statements, uri])

SQLite 原生只支持 5 种类型:TEXT、INTEGER、REAL、BLOB、NULL。
如果想用其它类型,必须自己添加相应的支持。

sqlite3.Connection类常用属性和方法:

  1. # 获取/设置 当前默认的隔离级别
  2. Connection.isolation_level
  3. # 获取游标, 返回 Cursor 实例
  4. Connection.cursor(factory=Cursor)
  5. # 提交当前事务。如果没有调用该方法,则从上一次 commit() 以来的所有变化在 其他数据库连接 上都不可见。
  6. Connection.commit()
  7. # 回滚到上一次 commit() 以来的所有数据库的改变
  8. Connection.rollback()
  9. # 关闭数据库连接。注意,该方法不会自动 commint()
  10. Connection.close()
  11. # 备份数据库,target 为 Connection 实例
  12. Connection.backup(target, *, pages=-1, progress=None,
  13. name="main", sleep=0.250)
  14. # 执行 SQL 语句的快捷方法,Connection 上直接执行 SQL 语句是 非标准的,
  15. # 它会先调用 cursor() 方法创建一个游标对象后再执行 SQL 语句。
  16. Connection.execute(sql[, parameters])
  17. Connection.executemany(sql[, parameters])
  18. Connection.executescript(sql_script)

Python3 SQLite3 的「事务控制」说明

1.2 Cursor

sqlite3.Cursor类常用属性和方法:

  1. # 执行单条 SQL 语句,可参数化语句(参数值使用占位符),支持两种占位符: 问号 和 命名占位符。
  2. # 例如: cursor.execute("insert into people values (?, ?)", (who, age))
  3. Cursor.execute(sql[, parameters])
  4. # 一条 SQL 语句,使用多个参数序列,多次执行。
  5. # 例如: params = [(who0, age0), (who1, age1), ...]
  6. # cursor.executemany("insert into people values (?, ?)", params)
  7. Cursor.executemany(sql, seq_of_parameters)
  8. # 执行 SQL 脚本,非标准的便捷方法。可用于一次执行多条 SQL 语句,
  9. # 它会首先执行一条 COMMIT 语句,再执行 SQL 脚本。
  10. # 例如: cursor.executescript("create ...; insert ...; select ...;")
  11. Cursor.executescript(sql_script)
  12. # 执行完一条查询的 SQL 语句后,获取该条 SQL 语句查询的结果集的下一行,
  13. # 返回一个单独序列,例如: (who1, age1),没有更多可用数据时返回 None。
  14. Cursor.fetchone()
  15. # 执行完一条查询的 SQL 语句后,获取该条 SQL 语句查询结果集的 size 行,
  16. # 返回一个列表,例如: [(who1, age1), (who2, age2)],没有更多可用行时将返回一个空列表。
  17. # 此方法是基于 size 参数尝试获取指定行,如果获取不到指定行数,实际结果可能返回较少的行数。
  18. Cursor.fetchmany(size=cursor.arraysize)
  19. # 执行完一条查询的 SQL 语句后,获取该条 SQL 语句查询的所有结果集(剩余所有行),
  20. # 返回一个列表,例如: [(who1, age1), (who2, age2), ...],没有可用行时将返回一个空列表。
  21. Cursor.fetchall()
  22. # 该只读属性将提供上一次 SQL 查询的列名称。为了与 Python DB API 保持兼容,
  23. # 它会为每个列返回一个 7 元组,每个元组的最后 6 个条目均为 None。
  24. # 例如: (
  25. # ('name', None, None, None, None, None, None),
  26. # ('age', None, None, None, None, None, None)
  27. # )
  28. # 对于没有任何匹配行的 SELECT 语句同样会设置该属性。
  29. Cursor.description
  30. # 立即关闭 cursor
  31. Cursor.close()

2. SQL 语句操作: CREATE / INSERT / SELECT / UPDATE / DELETE

  1. import sqlite3
  2. # 连接数据库
  3. conn = sqlite3.connect(":memory:")
  4. # 获取游标
  5. cursor = conn.cursor()
  6. # 创建表
  7. cursor.execute(""" create table if not exists Person( id integer primary key not null, name text not null, age integer not null ) """)
  8. # 插入数据
  9. cursor.execute("insert into Person(name, age) values(?, ?)", ("Tom1", 25))
  10. cursor.executemany("insert into Person(name, age) values(?, ?)",
  11. [("Tom2", 26), ("Tom3", 27), ("Tom4", 28)])
  12. # 查询数据
  13. cursor.execute("select * from Person")
  14. print(cursor.description) # (('id', None, ...), ('name', ...), ('age', ...))
  15. print(cursor.fetchall()) # [(1, 'Tom1', 25), (2, 'Tom2', 26), ...]
  16. # 更新数据
  17. cursor.execute("update Person set name=?, age=? where name=?", ("TOM111", 18, "Tom1"))
  18. cursor.execute("select * from Person where name=?", ("TOM111",))
  19. print(cursor.fetchone()) # (1, 'TOM111', 18)
  20. # 删除数据
  21. cursor.execute("delete from Person where id=?", (3,))
  22. cursor.execute("select * from Person where age>=?", (26,))
  23. print(cursor.fetchall()) # [(2, 'Tom2', 26), (4, 'Tom4', 28)]
  24. # 关闭游标
  25. cursor.close()
  26. # 提交事务
  27. conn.commit()
  28. # 关闭数据库连接
  29. conn.close()

执行结果:

  1. (('id', None, None, None, None, None, None), ('name', None, None, None, None, None, None), ('age', None, None, None, None, None, None))
  2. [(1, 'Tom1', 25), (2, 'Tom2', 26), (3, 'Tom3', 27), (4, 'Tom4', 28)]
  3. (1, 'TOM111', 18)
  4. [(2, 'Tom2', 26), (4, 'Tom4', 28)]

3. 通过「列名称」访问查询结果数据

  1. import sqlite3
  2. conn = sqlite3.connect(":memory:")
  3. cursor = conn.cursor()
  4. cursor.execute(""" create table if not exists Person( id integer primary key not null, name text not null, age integer not null ) """)
  5. cursor.execute("insert into Person(name, age) values(?, ?)", ("Tom1", 25))
  6. # 使用 sqlite3.Row 作为行工厂,
  7. # SELECT 查询结果的行数据将以 sqlite3.Row 实例的方式返回
  8. cursor.row_factory = sqlite3.Row
  9. # 执行 select 查询语句
  10. cursor.execute("select * from Person")
  11. # 遍历结果
  12. while True:
  13. row = cursor.fetchone() # 获取下一行
  14. if row is None:
  15. break
  16. print(row) # <sqlite3.Row object>
  17. print(row.keys()) # 所有列名称: ['id', 'name', 'age']
  18. print(row[0]) # 通过「索引」访问结果值
  19. print(row["id"]) # 通过「列名称」访问结果值(名称不区分大小写)
  20. assert row[1] == row["name"]
  21. assert row[2] == row["age"]
  22. # 也可以直接迭代 cursor, 迭代返回的元素为 Row 实例
  23. cursor.execute("select * from Person")
  24. for row in cursor:
  25. print(row) # <sqlite3.Row object>
  26. cursor.close()
  27. conn.commit()
  28. conn.close()

4. SQLite 和 Python 数据类型转换

SQLite 原生支持如下的 5 种类型: NULL, INTEGER, REAL, TEXT, BLOB

因此可以将以下 Python 类型发送到 SQLite 而不会出现任何问题:

  1. SAVE DATA
  2. -------------------------------------------
  3. Python --> SQLite
  4. -------------------------------------------
  5. None | NULL
  6. int | INTEGER
  7. float | REAL
  8. str | TEXT
  9. bytes | BLOB
  10. -------------------------------------------

SQLite 类型默认转换为 Python 类型的方式:

  1. READ DATA
  2. -------------------------------------------
  3. SQLite --> Python
  4. -------------------------------------------
  5. NULL | None
  6. INTEGER | int
  7. REAL | float
  8. TEXT | str
  9. BLOB | bytes
  10. -------------------------------------------

5. 数据库备份

将现有数据库复制到另一个数据库中:

  1. import sqlite3
  2. conn1 = sqlite3.connect("test1.db")
  3. conn2 = sqlite3.connect("test2.db")
  4. # 将数据库 test1.db 复制到 test2.db 中(如果 test2.db 已存在, 将被覆盖)
  5. conn1.backup(conn2)
  6. conn2.commit()
  7. conn1.close()
  8. conn2.close()

将现有数据库复制到临时副本中:

  1. import sqlite3
  2. conn1 = sqlite3.connect("test1.db")
  3. conn2 = sqlite3.connect(":memory:")
  4. conn1.backup(conn2)
  5. conn2.commit()
  6. conn1.close()
  7. conn2.close()

6. 使用 Connection 作为上下文管理器

连接对象Connection支持使用with用来作为上下文管理器,它可以自动提交或者回滚事务。如果出现异常,事务会被回滚conn.rollback();否则,事务会被提交conn.commit()

  1. import sqlite3
  2. conn = sqlite3.connect(":memory:")
  3. conn.execute("create table Person(id integer primary key, name text unique)")
  4. # 成功后, conn.commit() 会自动调用
  5. with conn:
  6. conn.execute("insert into Person(name) values (?)", ("Tom",))
  7. # 当 with 块以异常结束后会自动调用 conn.rollback(), 并且异常仍然会被抛出, 必须手动捕获异常。
  8. try:
  9. with conn:
  10. conn.execute("insert into Person(name) values (?)", ("Tom",))
  11. except sqlite3.IntegrityError as e:
  12. print("Error: " + str(e)) # Error: UNIQUE constraint failed: Person.name
  13. # 作为上下文管理器的连接对象只提交或回滚事务, 还需要手动关闭连接对象
  14. conn.close()

发表评论

表情:
评论列表 (有 0 条评论,757人围观)

还没有评论,来说两句吧...

相关阅读