SQLite在Pyhont中的使用,在本文中,我们将解决 SQLite 的问题。我们将学习如何通过名为sqlite3的 Python 库使用 SQLite 。最后,我们将探索 提供的一些更高级的功能,sqlite3
以使我们的工作更轻松。
什么是SQLite?
SQLite的座右铭是:“小。快速地。可靠的。随便选三个。”
SQLite 是一个用 C 编写的嵌入式数据库库。您可能熟悉其他数据库技术,如 MySQL 或 PostgreSQL。它们使用客户端-服务器方法:数据库作为服务器安装,然后使用客户端连接到它。SQLite 则不同:它被称为嵌入式数据库,因为它作为库包含在程序中。所有数据都存储在一个文件中——通常带有.db
扩展名——并且您拥有允许您运行 SQL 语句或对数据库执行任何其他操作的函数。
基于文件的存储解决方案还提供并发访问,这意味着多个进程或线程可以访问同一个数据库。好了,那么SQLite的用法有哪些呢?它适用于任何类型的应用程序吗?
好吧,在一些情况下 SQLite 表现出色:
- SQLite 包含在大多数移动操作系统(如 Android 和 iOS)中,如果您想要一个独立且无服务器的数据存储解决方案,它可能是一个完美的选择。
- 您可以利用SQL的强大功能并将所有数据放入单个 SQLite 数据库,而不是使用巨大的 CSV 文件。
- SQLite 可用于存储应用程序的配置数据。事实上,SQLite比配置文件等基于文件的系统快 35% 。
另一方面,不选择 SQLite 的原因有哪些?
- 与 MySQL 或 PostgreSQL 不同,SQLite 缺乏多用户功能。
- SQLite 仍然是基于文件的数据存储解决方案,而不是服务。您不能将它作为一个进程来管理,您不能启动或停止它,也不能管理资源使用。
SQLite 的 Python 接口
正如我在介绍中所说,SQLite 是一个 C 库。虽然有很多语言编写的接口,包括 Python。该sqlite3
模块提供 SQL 接口,至少需要 SQLite 3.7.15。
很棒的是sqlite3
Python自带的,所以你不需要安装任何东西。
开始使用sqlite3
是时候编码了!在第一部分中,我们将创建一个基本数据库。首先要做的是创建一个数据库并连接到它:
import sqlite3 dbName = 'database.db' try: conn = sqlite3.connect(dbName) cursor = conn.cursor() print("Database created!") except Exception as e: print("Something bad happened: ", e) if conn: conn.close()
在第 1 行,我们导入sqlite3
库。然后,在try/except
代码块内,我们调用sqlite3.connect()
以初始化与数据库的连接。如果一切顺利,conn
将成为该Connection
对象的一个实例。如果try
失败,我们打印收到的异常并关闭与数据库的连接。正如官方文档中所述,每个打开的 SQLite 数据库都由一个Connection
对象表示。每次我们必须执行 SQL 命令时,该Connection
对象都有一个名为cursor()
. 在数据库技术中,游标是一种控制结构,可以遍历数据库中的记录。
现在,如果我们执行这段代码,我们应该得到以下输出:
> Database created!
如果我们查看 Python 脚本所在的文件夹,我们应该会看到一个名为database.db
. 该文件由 自动创建sqlite3
。
创建、读取和修改记录
此时,我们已准备好创建一个新表,添加第一个条目并执行 SQL 命令,如SELECT
,UPDATE
或DROP
。
要创建表,我们只需要执行一条简单的 SQL 语句即可。在此示例中,我们将创建一个包含以下数据的学生表:
ID | 姓名 | 姓 |
---|---|---|
1个 | 约翰 | 史密斯 |
2个 | 露西 | 雅各布斯 |
3个 | 斯蒂芬 | 泰勒 |
在该print("Database created!")
行之后,添加:
# Create operation create_query = '''CREATE TABLE IF NOT EXISTS student( id INTEGER PRIMARY KEY, name TEXT NOT NULL, surname TEXT NOT NULL); ''' cursor.execute(create_query) print("Table created!") # Insert and Read operation cursor.execute("INSERT INTO student VALUES (1, 'John', 'Smith')") print("Insert #1 done!") cursor.execute("INSERT INTO student VALUES (2, 'Lucy', 'Jacobs')") print("Insert #2 done!") cursor.execute("INSERT INTO student VALUES (3, 'Stephan', 'Taylor')") print("Insert #3 done!") conn.commit() conn.close()
我们创建一个表并调用该cursor.execute()
方法,当我们要执行单个 SQL 语句时使用该方法。
然后,我们INSERT
为要添加的每一行做一个。完成所有更改后,我们调用conn.commit()
将挂起的事务提交到数据库。如果不调用该commit()
方法,对数据库的任何未决更改都将丢失。最后,我们通过调用conn.close()
方法关闭与数据库的连接。
好的,现在让我们查询我们的数据库!我们需要一个变量来保存我们的查询结果,所以让我们将结果保存cursor.execute()
到一个名为的变量中records
:
records = cursor.execute("SELECT * FROM student") for row in findrecords: print(row)
执行此操作后,我们将看到所有记录到stdout
:
(1, 'John', 'Smith') (2, 'Lucy', 'Jacobs') (3, 'Stephan', 'Taylor')
此时,您可能已经注意到,在cursor.execute()
方法内部,我们放置了必须执行的 SQL 命令。如果我们想执行另一个 SQL 命令,如UPDATE
或,Python 语法没有任何变化DROP
。
占位符
该cursor.execute()
方法需要一个字符串作为参数。在上一节中,我们看到了如何将数据插入到我们的数据库中,但是一切都是硬编码的。如果我们需要在数据库中存储变量中的内容怎么办?出于这个原因,sqlite3
有一些奇特的东西叫做占位符。占位符允许我们使用参数替换,这将使将变量插入查询变得更加容易。
让我们看看这个例子:
def insert_command(conn, student_id, name, surname): command = 'INSERT INTO student VALUES (?, ?, ?)' cur = conn.cursor() cur.execute(command, (student_id, name, surname, )) conn.commit()
我们创建一个名为的方法insert_command()
。这个方法有四个参数:第一个是一个Connection
实例,另外三个将在我们的 SQL 命令中使用。
变量?
内部的每个代表一个占位符。command
这意味着,如果您使用,和调用insert_command
函数,语句将变为。student_id=1
name='Jason'
surname='Green'
INSERT
INSERT INTO student VALUES(1, 'Jason', 'Green')
当我们调用该execute()
函数时,我们将我们的命令和所有将被替换为占位符的变量传递。从现在开始,每次我们需要在学生表中插入一行时,我们都会调用insert_command()
带有所需参数的方法。
事务
即使您对交易的定义并不陌生,让我快速回顾一下它的重要性。事务是在逻辑上被视为单个单元的数据库上执行的一系列操作。
事务最重要的好处是确保数据完整性。它在我们上面介绍的示例中可能没有用,但是当我们处理存储在多个表中的更多数据时,事务确实会有所作为。
Python 的模块在execute()和executemany()执行, , , or语句sqlite3
之前启动事务。这意味着两件事:INSERT
UPDATE
DELETE
REPLACE
- 我们必须注意调用
commit()
方法。如果我们Connection.close()
不执行 a调用commit()
,我们在事务期间所做的所有更改都将丢失。 - 我们不能在同一进程中使用
BEGIN
.
解决方案?显式处理事务。
如何?通过使用函数调用sqlite3.connect(dbName, isolation_level=None)
而不是sqlite3.connect(dbName)
. 通过设置isolation_level
为None
,我们强制sqlite3
永远不会隐式打开事务。
下面的代码是对前面代码的重写,但是明确地使用了事务:
import sqlite3 dbName = 'database.db' def insert_command(conn, student_id, name, surname): command = 'INSERT INTO student VALUES (?, ?, ?)' cur = conn.cursor() cur.execute("BEGIN") try: cur.execute(command, (student_id, name, surname, )) cur.execute("COMMIT") except conn.Error as e: print("Got an error: ", e) print("Aborting...") cur.execute("ROLLBACK") conn = sqlite3.connect(dbName, isolation_level=None) cursor = conn.cursor() print("Database created!") # Create operation create_query = '''CREATE TABLE IF NOT EXISTS student( id INTEGER PRIMARY KEY, name TEXT NOT NULL, surname TEXT NOT NULL); ''' cursor.execute(create_query) print("Table created!") # Insert and Read operation insert_command(conn , 1, 'John', 'Smith') insert_command(conn , 2, 'Lucy', 'Jacobs') insert_command(conn , 3, 'Stephan', 'Taylor') insert_command(conn , 4, 'Joseph', 'Random') findRecords = cursor.execute("SELECT * FROM student") for row in findRecords: print(row) conn.close()
结论
我希望您现在已经很好地了解 SQLite 是什么、如何将它用于 Python 项目以及它的一些高级功能如何工作。事务的显式管理一开始可能有点棘手,但它肯定可以帮助您充分利用sqlite3
.