【Python从入门到进阶】54、使用Python轻松操作SQLite数据库

一、引言

1、什么是SQLite

SQLite的起源可以追溯到2000年,由D. Richard Hipp(理查德·希普)所创建。作为一个独立的开发者,Hipp在寻找一个能够在嵌入式系统中使用的轻量级数据库时,发现现有的解决方案要么过于庞大,要么无法满足他的需求。因此,他决定自己开发一个简单、高效、可靠的数据库引擎,这就是SQLite的雏形。

SQLite的创始理念是提供一个无服务器的、零配置的、自给自足的数据库引擎,以解决嵌入式系统和移动设备的存储和查询问题。与传统的关系型数据库管理系统(RDBMS)不同,SQLite不需要独立的服务器进程,也不需要进行繁琐的配置和管理。它只需要一个数据库文件,就可以开始使用,极大地简化了数据库的使用和管理。

随着SQLite的不断发展,它逐渐成为了嵌入式系统和移动应用中的首选数据库。由于其小巧的体积、高效的性能和稳定的性能,SQLite被广泛应用于各种领域,如智能家居、医疗设备、移动设备、游戏等。同时,由于其开源免费的特性,SQLite也吸引了大量的开发者和用户,形成了一个庞大的社区。

在SQLite的发展过程中,Hipp一直致力于提高数据库的性能和稳定性,同时也不断扩展其功能。SQLite支持标准的SQL92语言,并且提供了丰富的API接口,使得开发者可以轻松地与数据库进行交互。此外,SQLite还支持事务处理、并发访问、索引、触发器等多种高级特性,为开发者提供了更加灵活和强大的数据存储和查询能力。

2、为什么Python是操作SQLite的理想选择

SQLite以其小巧的体积和出色的性能,成为了开发者们的得力助手。无论是快速搭建一个原型系统,还是作为移动应用的数据存储后端,SQLite都能提供稳定可靠的数据支持。而且,由于其开源免费的特性,SQLite得到了广大开发者的青睐。

Python作为一种流行的高级编程语言,凭借其简洁的语法、丰富的库和强大的扩展性,成为了众多开发者的首选。而Python内置的sqlite3模块,则为我们提供了与SQLite数据库交互的便利。通过Python,我们可以轻松地连接到SQLite数据库,执行SQL语句,进行数据的增删改查等操作。

在本文中,我们将介绍如何使用Python操作SQLite数据库,包括连接数据库、创建和操作表、查询数据等基础知识,希望通过本文的介绍,读者能够掌握Python操作SQLite的基本技能,为日后的项目开发打下坚实的基础。

二、安装SQLite和Python的SQLite库

1、安装SQLite

SQLite不需要一个单独的服务器进程或操作系统级别的配置,因为它只是一个磁盘文件上的库,并且可以在多种编程语言中直接使用。

我们可以从SQLite的官方网站(https://www.sqlite.org/download.html)下载并安装。
在官网的【download】菜单下,找到“Precompiled Binaries for Windows”区域,下载相关版本(我这里是Windows的64位操作系统,所以选择x64版本):

这里下载数据库和命令行工具两个压缩包
下载完毕之后,解压压缩包:

可以看到sqlite-dll-win-x64-3450300.zip里面只有两个文件,分别是“sqlite3.def”和“sqlite3.dll”。sqlite-tools-win-x64-3450300.zip中是一个“”文件,我们新建一个sqlite3文件夹,将这些文件放在一个文件夹中:

添加“D:\Program Files (x86)\sqlite3”到电脑的PATH环境变量:

最后在命令提示符下,使用sqlite3命令,将显示如下结果:

这就证明咱们的sqlite安装成功。

2、安装Python的SQLite库

对于Python来说,SQLite库(sqlite3)是内置的,这意味着咱们不需要额外安装任何包来使用它。从Python2.5开始,sqlite3模块就被包含在Python的标准库中。要验证你的Python环境中是否包含了sqlite3模块,可以打开Python解释器并尝试导入它:

import sqlite3  

# 如果没有报错,说明sqlite3模块已经成功导入  
print("sqlite3 module is available.")

效果:

如果输出显示“sqlite3 module is available.”,那么你就可以开始使用Python来操作SQLite数据库了。如果你遇到任何导入错误,那么可能是因为你的Python环境有问题,或者你的Python版本太旧(低于2.5)。在这种情况下,需要更新Python环境或安装一个更新的版本。

三、连接到SQLite数据库

在Python中,我们可以使用内置的sqlite3模块来连接SQLite数据库。SQLite数据库文件实际上就是一个磁盘上的文件,通过这个文件,我们可以对数据进行存储、查询、更新和删除等操作。

1. 导入sqlite3模块

首先,我们需要在Python脚本中导入sqlite3模块。这个模块提供了与SQLite数据库交互的所有必要功能。

import sqlite3

2. 连接到SQLite数据库

然后,我们使用sqlite3.connect()函数来连接SQLite数据库。这个函数接受一个参数,即数据库文件的路径。如果指定的数据库文件不存在,SQLite会自动创建一个新的数据库文件。

# 连接到SQLite数据库文件,如果不存在则创建它  
conn = sqlite3.connect('example.db')

在上面的代码中,我们尝试连接到名为example.db的SQLite数据库文件。如果该文件不存在于指定的位置,SQLite将创建一个新的数据库文件。

3. 创建游标对象

在连接到数据库之后,我们需要创建一个游标(cursor)对象。游标对象用于执行SQL命令和获取查询结果。

# 创建一个游标对象  
cursor = conn.cursor()

4. 执行SQL命令

现在,我们可以使用游标对象来执行SQL命令了。例如,我们可以使用cursor.execute()方法创建一个新的表,或者向表中插入数据。

# 创建一个示例表  
cursor.execute('''  
    CREATE TABLE IF NOT EXISTS users (  
        id INTEGER PRIMARY KEY,  
        name TEXT,  
        age INTEGER  
    )  
''')  
  
# 插入一条数据  
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ("魏大勋", 30))

在上面的代码中,我们首先使用CREATE TABLE语句创建了一个名为users的表(如果该表已经存在,则不会执行创建操作)。然后,我们使用INSERT INTO语句向表中插入了一条数据。注意,我们使用参数化查询来插入数据,这样可以防止SQL注入攻击。

5. 提交事务并关闭连接

在执行完SQL命令后,我们需要调用conn.commit()方法来提交事务,以确保数据被保存到数据库中。最后,我们使用conn.close()方法来关闭数据库连接。

# 提交事务  
conn.commit()  
  
# 关闭连接  
conn.close()

6. 完整的示例代码

下面是一个完整的示例代码,展示了如何连接到SQLite数据库、创建表、插入数据、提交事务并关闭连接:

import sqlite3  
  
# 连接到SQLite数据库文件,如果不存在则创建它  
conn = sqlite3.connect('example.db')  
  
# 创建一个游标对象  
cursor = conn.cursor()  
  
# 创建一个示例表  
cursor.execute('''  
    CREATE TABLE IF NOT EXISTS users (  
        id INTEGER PRIMARY KEY,  
        name TEXT,  
        age INTEGER  
    )  
''')  
  
# 插入一条数据  
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ("魏大勋", 30))  
  
# 提交事务  
conn.commit()  
  
# 关闭连接  
conn.close()

四、创建和操作SQLite表

在SQLite数据库中,表是存储数据的基本结构。通过表,我们可以定义数据的结构和关系。在Python中,我们可以使用sqlite3模块来创建和操作SQLite表。

1. 创建表

要创建一个新的表,我们需要使用CREATE TABLE语句,并通过游标对象执行该语句。下面是一个创建表的示例:

import sqlite3  
  
# 连接到SQLite数据库(如果数据库不存在,会自动在当前目录创建)  
conn = sqlite3.connect('test.db')  
  
# 创建一个游标对象  
cursor = conn.cursor()  
  
# 创建一个名为users的表  
create_table_sql = '''  
CREATE TABLE IF NOT EXISTS users (  
    id INTEGER PRIMARY KEY AUTOINCREMENT,  
    name TEXT NOT NULL,  
    age INTEGER,  
    email TEXT UNIQUE  
)  
'''  
cursor.execute(create_table_sql)  
  
# 提交事务(在创建表时通常不需要,但在这里为了保持一致性)  
conn.commit()  
  
# 关闭游标和连接  
cursor.close()  
conn.close()

在这个示例中,我们创建了一个名为users的表,它包含四个字段:id(作为主键并自动增长)、name(不能为空)、age(可以为空)和email(必须是唯一的)。

2. 插入数据

要向表中插入数据,我们可以使用INSERT INTO语句。下面是一个插入数据的示例:

import sqlite3  
  
# 连接到SQLite数据库  
conn = sqlite3.connect('test.db')  
  
# 创建一个游标对象  
cursor = conn.cursor()  
  
# 插入一条数据  
insert_sql = "INSERT INTO users (name, age, email) VALUES (?, ?, ?)"  
data = ('魏大勋', 30, 'weidaxun@example.com')  
cursor.execute(insert_sql, data)  
  
# 提交事务  
conn.commit()  
  
# 关闭游标和连接  
cursor.close()  
conn.close()

在这个示例中,我们使用参数化查询来插入数据,这不仅可以提高代码的可读性,还可以防止SQL注入攻击。

3. 查询数据

要从表中查询数据,我们可以使用SELECT语句。下面是一个查询数据的示例:

import sqlite3  
  
# 连接到SQLite数据库  
conn = sqlite3.connect('test.db')  
  
# 创建一个游标对象  
cursor = conn.cursor()  
  
# 查询所有数据  
query_sql = "SELECT * FROM users"  
cursor.execute(query_sql)  
  
# 获取查询结果  
results = cursor.fetchall()  
for row in results:  
    print(row)  
  
# 关闭游标和连接  
cursor.close()  
conn.close()

在这个示例中,我们使用fetchall()方法获取查询结果的所有行。我们还可以使用fetchone()方法逐行获取结果,或者使用fetchmany(size)方法一次获取多行结果。查询结果:

4. 更新数据

要更新表中的数据,我们可以使用UPDATE语句。下面是一个更新数据的示例:

import sqlite3

# 链接到SQLite数据库
conn = sqlite3.connect("test.db")

# 创建一个游标对象
cursor = conn.cursor()

# 查询更新前数据
query_sql = "select * from users where name = ?"
query_data = ("魏大勋",)  # 就算只有一个值,也必须用元组包裹
cursor.execute(query_sql, query_data)
results = cursor.fetchall()
print("[更新前数据]:", results)

# 更新一条数据
update_sql = "update users set age = ? where name = ?"
update_data = (30, "魏大勋")
cursor.execute(update_sql, update_data)

# 提交事务
conn.commit()

# 查询更新后数据
cursor.execute(query_sql, query_data)
results = cursor.fetchall()
print("[更新后数据]:", results)

# 关闭游标和连接
cursor.close()
conn.close()

在这个示例中,我们将名为'魏大勋'的用户的年龄更新为30。运行效果:

5. 删除数据

要从表中删除数据,我们可以使用DELETE语句。下面是一个删除数据的示例:

import sqlite3  
  
# 连接到SQLite数据库  
conn = sqlite3.connect('test.db')  
  
# 创建一个游标对象  
cursor = conn.cursor()  
  
# 删除一条数据  
delete_sql = "DELETE FROM users WHERE name = ?"  
data = ('魏大勋',)  
cursor.execute(delete_sql, data)  
  
# 提交事务  
conn.commit()  
  
# 关闭游标和连接  
cursor.close()  
conn.close()

在这个示例中,我们删除了名为'魏大勋'的用户。请注意,在执行删除操作时要特别小心,因为删除的数据将不可恢复。

五、使用Python的sqlite3模块高级功能

Python的sqlite3模块不仅提供了基本的数据库操作功能,如创建表、插入数据、查询数据等,还提供了一些高级功能,可以帮助我们更高效地管理和使用SQLite数据库。下面将介绍一些sqlite3模块的高级功能。

1. 参数化查询

参数化查询是一种防止SQL注入攻击的有效方法。在sqlite3中,我们可以使用问号(?)作为占位符,并将实际参数作为元组或列表传递给execute()方法。这样做不仅可以确保数据的安全性,还可以提高查询的性能。

import sqlite3  
  
# 连接到SQLite数据库  
conn = sqlite3.connect('test.db')  
cursor = conn.cursor()  
  
# 参数化查询  
name = 'Alice'  
query = "SELECT * FROM users WHERE name = ?"  
cursor.execute(query, (name,))  
results = cursor.fetchall()  
for row in results:  
    print(row)  
  
# 关闭游标和连接  
cursor.close()  
conn.close()

2. 执行事务

在SQLite中,事务是一组作为单个逻辑单元执行的SQL语句。使用事务可以确保数据的一致性,即使在出现错误时也可以回滚到事务开始之前的状态。在sqlite3中,我们可以使用commit()方法提交事务,使用rollback()方法回滚事务。

import sqlite3  
  
# 连接到SQLite数据库  
conn = sqlite3.connect('test.db')  
cursor = conn.cursor()  
  
try:  
    # 开始一个事务  
    cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('白敬亭', 25))  
    cursor.execute("UPDATE users SET age = ? WHERE name = ?", (26, '白敬亭'))  
    # 提交事务  
    conn.commit()  
except Exception as e:  
    # 发生异常时回滚事务  
    print(f"An error occurred: {e}")  
    conn.rollback()  
  
# 关闭游标和连接  
cursor.close()  
conn.close()

如果我们重复插入这个数据(我们设置email为唯一的),就会报错:

报的就是唯一策略的字段被重复插入了。

3. 使用ROWID

SQLite中的每个表都有一个特殊的ROWID列,它是一个64位整数,用于唯一标识表中的每一行。即使我们没有在表中明确指定主键列,SQLite也会自动为我们创建一个隐藏的ROWID列。我们可以使用ROWID来访问和操作表中的行。

import sqlite3  
  
# 连接到SQLite数据库  
conn = sqlite3.connect('test.db')  
cursor = conn.cursor()  
  
# 插入一条数据并获取ROWID  
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('彭昱畅', 28))  
rowid = cursor.lastrowid  
print(f"Inserted row with ROWID: {rowid}")  
  
# 使用ROWID查询数据  
query = "SELECT * FROM users WHERE rowid = ?"  
cursor.execute(query, (rowid,))  
result = cursor.fetchone()  
print(result)  
  
# 关闭游标和连接  
cursor.close()  
conn.close()

效果:

4. 使用内存数据库

除了磁盘上的文件数据库外,SQLite还支持内存数据库。内存数据库将数据存储在RAM中,因此读写速度非常快,但数据在关闭连接后会丢失。要创建内存数据库,只需将数据库文件名设置为:memory:即可。

import sqlite3  
  
# 连接到内存数据库  
conn = sqlite3.connect(':memory:')  
cursor = conn.cursor()  
  
# 在内存数据库中创建表并插入数据  
cursor.execute('''  
    CREATE TABLE users (  
        id INTEGER PRIMARY KEY AUTOINCREMENT,  
        name TEXT NOT NULL,  
        age INTEGER  
    )  
''')  
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('彭昱畅', 28))  
  
# 查询并打印数据  
cursor.execute("SELECT * FROM users")  
for row in cursor.fetchall():  
    print(row)  
  
# 关闭游标和连接(数据将丢失)  
cursor.close()  
conn.close()

效果:
​​​​​​​

5. 使用自定义数据类型

SQLite支持多种数据类型,但默认情况下,它可能无法直接处理某些复杂的数据结构(如列表、字典等)。然而,我们可以通过Python的序列化机制(如pickle)将这些数据结构转换为字节字符串,并在SQLite中将其存储为BLOB(二进制大对象)类型。然后,我们可以使用反序列化机制将这些字节字符串还原为原始数据结构。

请注意,使用这种方法存储复杂数据结构可能会增加数据处理的复杂性和安全风险,因此应谨慎使用。

转载请注明出处:https://guangzai.blog.csdn.net/article/details/138764428

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/617897.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DML操作表的数据

一、增加数据 语法: INSERT [INTO] 表名 [( 列名表 )] VALUES ( 值列表 ) 1.1 插入全部字段 l 所有的字段名都写出来 INSERT INTO 表名 (字段名1, 字段名2, 字段名3…) VALUES (值1, 值2, 值3); l 不写字段名 INSERT INTO 表名 VALUES (值1, 值2, 值3…); 注&…

吴恩达机器学习笔记:第 9 周-16推荐系统(Recommender Systems) 16.5-16.6

目录 第 9 周 16、 推荐系统(Recommender Systems)16.5 向量化:低秩矩阵分解16.6 推行工作上的细节:均值归一化 第 9 周 16、 推荐系统(Recommender Systems) 16.5 向量化:低秩矩阵分解 在上几节视频中,我们谈到了协同过滤算法&…

Unity VR在编辑器下开启Quest3透视(PassThrough)功能

现在有个需求是PC端串流在某些特定时候需要开启透视。我研究了两天发现一些坑,记录一下方便查阅,也给没踩坑的朋友一些思路方案。 先说结论,如果要打PC端或者在Unity编辑器中开启,那么OpenXR当前是不行的可能还需要一个长期的过程,必须需要切换到Oculus。当然Unity官方指…

胆子真大,敢搞B站

今天给大家分享一款浏览器插件,能让你的B站在电脑端访问时候会更高级 作者已经开源到Github Star数量还在持续上升中 来看下这款插件究竟具备哪些功能 首先是开启首页干净模式,也就是去除大屏 正常情况我们访问B站是这个样子的~ 开启总开关后 首页的视…

SM4-GCM Library代码示例

sm4-gcm加密解密测试代码: fn main() {let key Sm4Key([0u8; 16]);let nonce [0u8; 12];let plaintext b"Hello World!";let ciphertext sm4_gcm::sm4_gcm_encrypt(&key, &nonce, plaintext);println!("Encrypted: {}", hex::encode(&cip…

K-AI01,K-AO01,K-BUS02和利时

K-AI01,K-AO01,K-BUS02和利时1.将工程师站的计算机开机;2.开机后鼠标双击桌面上的“maintenance tool”图标,K-AI01,K-AO01,K-BUS02和利时。出现如下图标: 按顺序点击”图标中的箭头所指的按钮,出现如下画面选中画面中需要强制的逻…

MybatisPlus入门用法

目录 1.引入依赖 2.继承BaseMapper 常见注解 常见配置 1.引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency> 2.继承Bas…

next水和错误

产生原因 应该是和预渲染有关&#xff0c;官方也有谈到 水和错误主要原因 这个主要事服务器端渲染和客户端渲染结果不一致&#xff0c;客户端再渲染导致的错误&#xff0c;主要结果就是耗费性能&#xff0c;当然也可以关闭提示错误 具体解决措施可以看看官方文档参考 相关的…

ACE框架学习4

目录 ACE Proactor框架 异步I/O工厂类 ACE_Handler类 前摄式Acceptor-Connector类 ACE_Proactor类 ACE Streams框架 ACE_Model类 ACE_Streams类 ACE Proactor框架 ACE Proactor框架实现了proactor模式&#xff0c;也就是异步网络模式&#xff0c;允许事件驱动…

C++内存管理(2)+模版初阶

目录 1.内存的划分 2.内存泄漏 3.模版初阶 &#xff08;1&#xff09;模版的引入 &#xff08;2&#xff09;函数模版 &#xff08;3&#xff09;类模版 &#xff08;4&#xff09;类型的不匹配问题 1.内存的划分 &#xff08;1&#xff09;C里面&#xff0c;把内存划分为…

漫谈ApplicationContext和BeanFactory的区别

各位大佬光临寒舍&#xff0c;希望各位能赏脸给个三连&#xff0c;谢谢各位大佬了&#xff01;&#xff01;&#xff01; 目录 1.背景介绍 2.细述ApplicationContext和BeanFactory 3.总结 1.背景介绍 当我们使用SpringBoot创建项目的时候会看到一串代码&#xff1a…

全面理解BDD(行为驱动开发):转变思维方式,提升软件质量

在传统的软件开发流程中&#xff0c;开发人员和测试人员的工作通常是相互独立的。开发人员负责编写代码&#xff0c;测试人员负责找出代码中的问题。然而&#xff0c;这种方法可能导致沟通不足&#xff0c;而且会浪费时间和资源。为了解决这些问题&#xff0c;出现了一种新的开…

Linux cmake 初窥【3】

1.开发背景 基于上一篇的基础上&#xff0c;已经实现了多个源文件路径调用&#xff0c;但是没有库的实现 2.开发需求 基于 cmake 的动态库和静态库的调用 3.开发环境 ubuntu 20.04 cmake-3.23.1 4.实现步骤 4.1 准备源码文件 基于上个试验的基础上&#xff0c;增加了动态库…

电文加密(C语言)

一、题目说明&#xff1b; 即第1个字母变成第26个字母&#xff0c;第i个字母变成第(26 - i 1)个字母&#xff0c;非字母字符不变。 二、N-S流程图&#xff1b; 三、运行结果&#xff1b; 四、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h&g…

过拟合和欠拟合的学习

1.什么拟合 就是说这个曲线能不能很好地描述某些样本数据&#xff0c;并且拥有较好的泛化能力。 2.什么是过拟合 过拟合就是曲线太过于贴切训练数据的特征了&#xff0c;在训练集上表现得非常优秀&#xff0c;近乎完美的预测/区分了所有得数据&#xff0c;但是在新的测试集上…

LeetCode—用队列实现栈

一.题目 二.思路 1.后入先出的实现&#xff1a; 创建两个队列来实现栈&#xff08;后入先出&#xff09;&#xff1a; 两个队列&#xff0c;保持一个存数据&#xff0c;另一个为空&#xff0c;入数据&#xff08;push&#xff09;要入不为空的队列&#xff0c;&#xff08;p…

Linux基础之进程的基本概念

目录 一、进程的基本概念 1.1 什么是进程 1.2 PCB的概念 1.3 进程的查看 1.3.1 查看进程方式一 1.3.2 查看进程的方式二 1.4 父进程与子进程 一、进程的基本概念 1.1 什么是进程 进程是什么&#xff1f; 课本概念&#xff1a;程序的一个执行实例&#xff0c;正在执行的…

Linux学习笔记8---官方 SDK 移植实验

在上一章中&#xff0c;我们参考 ST 官方给 STM32 编写的 stm32f10x.h 来自行编写 I.MX6U 的寄存器定义文件。自己编写这些寄存器定义不仅费时费力&#xff0c;没有任何意义&#xff0c;而且很容易写错&#xff0c;幸好NXP 官方为 I.MX6ULL 编写了 SDK 包&#xff0c;在 SDK 包…

基于springboot+vue+Mysql的校园闲置物品租售系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

C++小程序:同一路由器下两台计算机间简单通信(2/2)——客户端

客户端的程序结构前半部分与服务器端基本相同&#xff0c;后半部分也相对简单。相关函数的解释可以参考前文服务器端的内容。有关客户端的内容除个别地方外&#xff0c;就不再做长篇大论的解释。强调一点&#xff0c;如果将此程序移到其它电脑上运行&#xff0c;编译需要releas…