如何在 Python 3 中使用 sqlite3 模块

作者选择了 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 数据库中,数据存储在表中。

我们将创建一个名为的表,该表追踪以下数据:

namespeciestank_number
Sammyshark1
Jamiecuttlefish7

表将追踪每个鱼在水族馆的名称,物种库存号的值. 列出了两个的示例行:一个名为萨米鲨鱼的行,一个名为杰米小鱼的行。

我们可以使用我们在步骤 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,speciestank_number列的值。fetchall()函数检索了SELECT语句的所有结果。当我们打印(行)时,我们会看到一份两个列表。每个列有三个条目;我们从fish表中选择的每个列一个条目。两个列有我们在步骤2中输入的数据:一个列为Sammy鲨鱼,一个列为Jamiecuttlefish

如果我们想在表中检索符合特定标准的行,我们可以使用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().fetchall()’允许我们检索一个‘SELECT’陈述的所有结果。在‘SELECT’陈述中的‘WHERE’条款对‘name’值为‘target_fish_name’的行进行过滤。 请注意,我们使用‘?’来代替我们的‘target_fish_name’变量为‘SELECT’陈述。 我们预计只会匹配一个行,而且我们只会看到‘Jamie’的‘cuttlefish’返回。

<$>[警告] 警告: 永远不要使用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 语句以将Sammytank_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

Published At
Categories with 技术
comments powered by Disqus