作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分接受捐款。
介绍
SQLite是一个自包含的,基于文件的SQL数据库。SQLite配备了 Python并可以在任何Python应用程序中使用,而无需安装任何额外的软件。
在本教程中,我们将通过Python 3中的「sqlite3」模块(「LINK0」)。我们将创建与SQLite数据库的连接,将表添加到该数据库中,将数据插入到该表中,并阅读和修改该表中的数据。
对于本教程,我们将主要与我们需要修改的鱼类库存工作,因为鱼被添加到或从虚构的水族馆中删除。
前提条件
为了充分利用本教程,建议您熟悉Python编程和一些基本的SQL背景。
您可以查看这些教程以获取必要的背景信息:
步骤 1 — 创建与 SQLite 数据库的连接
当我们连接到SQLite数据库时,我们正在访问最终居住在计算机上的文件中的数据。SQLite数据库是完整的SQL引擎,可以用于许多目的。
我们可以使用 Python sqlite3
模块连接到 SQLite 数据库:
1import sqlite3
2
3connection = sqlite3.connect("aquarium.db")
「輸入 sqlite3」讓我們的Python程式可以存取「sqlite3」模組.「sqlite3.connect()」函數會返回一個「連接」(https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection)對象,我們將用來與存放在「aquarium.db」檔案中的SQLite資料庫互動。
我们可以验证我们成功创建了我们的连接
对象,运行:
1print(connection.total_changes)
如果我们运行这个Python代码,我们会看到这样的输出:
1[secondary_label Output]
20
'connection.total_changes' 是由 'connection' 更改的数据库行总数.由于我们尚未执行任何 SQL 命令,所以 0 'total_changes' 是正确的。
如果,在任何时候,我们发现我们想要重新启动这个教程,我们可以从我们的计算机中删除aquarium.db
文件。
<$>[注]
注: 也可以通过将特殊字符串 :memory:"
传输到 sqlite3.connect()
来连接到严格存在于内存(而不是文件)的 SQLite 数据库。例如, sqlite3.connect(":memory:")
. A :memory:"
SQLite 数据库将在您的 Python 程序退出后消失。
步骤 2 – 将数据添加到 SQLite 数据库
现在我们已连接到 SQLite 数据库 aquarium.db
,我们可以开始插入和读取数据。
在 SQL 数据库中,数据存储在表中。
我们将创建一个名为鱼
的表,该表追踪以下数据:
name | species | tank_number |
---|---|---|
Sammy | shark | 1 |
Jamie | cuttlefish | 7 |
鱼
表将追踪每个鱼在水族馆的名称
,物种
和库存号
的值. 列出了两个鱼
的示例行:一个名为萨米
的鲨鱼
的行,一个名为杰米
的小鱼
的行。
我们可以使用我们在步骤 1 中所做的连接
在 SQLite 中创建这个鱼
表:
1cursor = connection.cursor()
2cursor.execute("CREATE TABLE fish (name TEXT, species TEXT, tank_number INTEGER)")
connection.cursor()
返回一个 Cursor
对象。 Cursor
对象允许我们使用 cursor.execute()
将 SQL 陈述发送到 SQLite 数据库。 "CREATE TABLE fish..."' 字符串是创建一个名为
fish 的 SQL 陈述,其中包含前面描述的三个列: name
类型 TEXT
, 类型 TEXT
, 类型 INTEGER
类型 `tank_number。
现在我们已经创建了一个表,我们可以插入数据行:
1cursor.execute("INSERT INTO fish VALUES ('Sammy', 'shark', 1)")
2cursor.execute("INSERT INTO fish VALUES ('Jamie', 'cuttlefish', 7)")
我们呼叫cursor.execute()
两次:一次将鲨鱼Sammy
的行插入罐头1
,一次将小鱼Jamie
的行插入罐头7
。
在下一节中,我们将使用SQLSELECT
陈述来检查我们刚刚插入到我们的鱼
表中的行。
步骤 3 – 从 SQLite 数据库读取数据
在步骤 2 中,我们将两个行添加到一个名为fish
的 SQLite 表中,我们可以使用一个SELECT
SQL 语句来检索这些行:
1rows = cursor.execute("SELECT name, species, tank_number FROM fish").fetchall()
2print(rows)
如果我们运行此代码,我们将看到如下的输出:
1[secondary_label Output]
2[('Sammy', 'shark', 1), ('Jamie', 'cuttlefish', 7)]
cursor.execute()
函数运行一个SELECT
语句来检索fish
表中的name
,species
和tank_number
列的值。fetchall()
函数检索了SELECT
语句的所有结果。当我们打印(行)
时,我们会看到一份两个列表。每个列有三个条目;我们从fish
表中选择的每个列一个条目。两个列有我们在步骤2中输入的数据:一个列为Sammy
的鲨鱼
,一个列为Jamie
的cuttlefish
。
如果我们想在鱼
表中检索符合特定标准的行,我们可以使用WHERE
条款:
1target_fish_name = "Jamie"
2rows = cursor.execute(
3 "SELECT name, species, tank_number FROM fish WHERE name = ?",
4 (target_fish_name,),
5).fetchall()
6print(rows)
如果我们运行此操作,我们将看到如下结果:
1[secondary_label Output]
2[('Jamie', 'cuttlefish', 7)]
与前一个例子一样,‘cursor.execute(
<$>[警告] 警告: 永远不要使用Python字符串操作来动态创建一个SQL字符串操作。使用Python字符串操作来组装一个SQL字符串使你容易受到 SQL注入攻击的攻击。SQL注入攻击可以用来窃取、改变或以其他方式修改存储在你的数据库中的数据。 始终在你的SQL字符串中使用‘?‘位持有者来动态地取代你的Python程序的值。 将一个值堆作为第二个论点传递到‘Cursor.execute()’来将你的值绑定到SQL字符串中。 这个替代模式在这里和本教程的其他部分也展示了。 <$>
步骤 4 – 修改 SQLite 数据库中的数据
SQLite 数据库中的行可以使用更新
和删除
SQL 语句进行修改。
例如,假设Sammy鲨鱼被移动到2号坦克,我们可以改变Sammy在鱼
表中的行,以反映这种变化:
1new_tank_number = 2
2moved_fish_name = "Sammy"
3cursor.execute(
4 "UPDATE fish SET tank_number = ? WHERE name = ?",
5 (new_tank_number, moved_fish_name)
6)
我们发出一个更新
SQL 语句以将Sammy
的tank_number
更改为其新值为2
。
如果我们运行以下SELECT
声明,我们可以确认我们的更新是正确的:
1rows = cursor.execute("SELECT name, species, tank_number FROM fish").fetchall()
2print(rows)
如果我们运行此操作,我们将看到如下结果:
1[secondary_label Output]
2[('Sammy', 'shark', 2), ('Jamie', 'cuttlefish', 7)]
请注意,Sammy
的行现在对其tank_number
列具有2
的值。
假设Sammy鲨鱼被释放到野外,不再被水族馆持有,因为Sammy不再生活在水族馆里,所以从鱼
桌上删除Sammy
行是有意义的。
发出一个DELETE
SQL 语句来删除行:
1released_fish_name = "Sammy"
2cursor.execute(
3 "DELETE FROM fish WHERE name = ?",
4 (released_fish_name,)
5)
我们发出一个DELETE
SQL 语句,以删除Sammy
的行鲨鱼
。
如果我们运行以下SELECT
声明,我们可以确认我们的删除是正确的:
1rows = cursor.execute("SELECT name, species, tank_number FROM fish").fetchall()
2print(rows)
如果我们运行此代码,我们将看到如下的输出:
1[secondary_label Output]
2[('Jamie', 'cuttlefish', 7)]
注意,萨米
这个鲨鱼
的行已经消失了,只剩下杰米
这个小鱼
了。
步骤 5 — 使用与
声明进行自动清理
在本教程中,我们使用了两个主要对象与SQLite数据库aquarium.db
进行交互:一个名为连接
的连接
的连接
的连接
的连接
的连接
的连接
的连接
的连接
的指针
的指针
的指针
的指针
。
就像我们完成工作时应该关闭Python文件一样,连接
和指针
对象也应该关闭,当它们不再需要时。
我们可以使用一个与
语句来帮助我们自动关闭连接
和指针
对象:
1from contextlib import closing
2
3with closing(sqlite3.connect("aquarium.db")) as connection:
4 with closing(connection.cursor()) as cursor:
5 rows = cursor.execute("SELECT 1").fetchall()
6 print(rows)
「關閉」是由「contextlib」模組提供的便利函數(「LINK0」)。當一個「與」陳述退出時,「關閉」會確保任何被傳送到該對象上的「 close()」都被召喚。在本例中,「關閉」函數被使用兩次。
如果我们运行此代码,我们将看到如下的输出:
1[secondary_label Output]
2[(1,)]
由于SELECT 1
是一个 SQL 语句,它总是返回一个单行和一个单一的列值为1
,所以将一个单一的 tuple 视为其唯一的值,由我们的代码返回。
结论
sqlite3
模块是Python标准库的强大组成部分,它允许我们在不需要安装任何额外的软件的情况下使用完全可用的磁盘上的SQL数据库。
在本教程中,我们学习了如何使用sqlite3
模块连接到SQLite数据库,添加数据到该数据库,以及阅读和修改该数据库中的数据。
从这里我们可以了解更多关于SQL数据库的信息 SQLite vs MySQL vs PostgreSQL: A Comparison Of Relational Database Management Systems。