Python 数据持久化:使用 SQLite3 进行简单而强大的数据存储

news2024/10/6 6:00:02

🍀 前言

博客地址:

  • CSDN:https://blog.csdn.net/powerbiubiu

👋 简介

SQLite3是一种轻量级嵌入式数据库引擎,它在Python中被广泛使用。SQLite3通常已经包含在Python标准库中,无需额外安装。你只需导入 sqlite3 模块即可开始使用,不仅可以实现数据的持久化操作,还能对数据进行增删改查的功能。

📖 正文

1 SQLite3的使用

1.1 连接数据库

如果连接的数据库不存在则创建,
以下代码在python文件同级目录下创建一个test.db文件

import sqlite3
# 连接到数据库(如果不存在则创建)
connection = sqlite3.connect('test.db')
1.2 创建表

创建一个users表,其中包含id,name,age

# 创建表
cursor.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
# 提交更改
connection.commit()
1.3 插入数据
# 插入数据
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('李四', 18))
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('张三', 20))
#
# 提交更改
connection.commit()
print(cursor.rowcount)
print(cursor.lastrowid)

# 1
# 2

Tips:
SQLite3在执行多条数据插入,并且commit提交后,rowcount只会返回最后一次插入影响的行,也就是1,而lastrowid只返回插入的最后一条数据的id。

1.4 查询数据

首先在控制台中通过sqlite3 test.db连接数据库,在通过select * from users;可以查询到我们刚才添加的数据
image.png
通过代码查询,我们发现,返回的数据和连接数据库查询的一致
通过代码查询返回的是一个列表

# 查询数据
cursor.execute("SELECT * FROM users")
# 获取所有行
rows = cursor.fetchall()
print(rows)
print(type(rows))

# [(1, '李四', 18), (2, '张三', 20)]
# <class 'list'>

如果查询一个数据,返回的结果,仍然是列表保存的元组数据

# 查询数据
cursor.execute("SELECT * FROM users WHERE id = 1")
# 获取所有行
rows = cursor.fetchall()
print(rows)
print(type(rows))

# [(1, '李四', 18)]
# <class 'list'>
1.5 更新数据

将id为1的name改成王五

# 更新数据
cursor.execute("UPDATE users SET name = ? WHERE id = ?", ('王五', 1))
connection.commit()
# 打印受影响的行
print(cursor.rowcount)

# 1

这时,我们在查询一下结果,发现id为1的数据被修改了

# 查询数据
cursor.execute("SELECT * FROM users")
# # 获取所有行
rows = cursor.fetchall()
print(rows)

# [(1, '王五', 18), (2, '张三', 20)]
1.6 删除数据

与更新操作一样,删除成功后会返回受影响的行。
备注:需要注意,第二个参数传入元组时,只有一个元素的情况下,需要加个,号,表示该参数为元组

cursor.execute("DELETE FROM users WHERE id = ?", (1,))
connection.commit()
print(cursor.rowcount)

# 1
1.7 关闭连接
# 关闭游标和连接
cursor.close()
connection.close()

2 上下文管理器操作SQLite3

with sqlite3.connect('test.db') as connection:
    cursor = connection.cursor()
    # 执行数据库操作
    cursor.execute("SELECT * FROM users")
    rows = cursor.fetchall()
    
print(rows)
# [(1, '李四', 18), (2, '张三', 20)]

这种方式方便好用,可以不用手动编写关闭游标和连接的代码,与with open()是使用方式相同。

3 封装工具类

import sqlite3


class SQLite3Tools:
    def __init__(self, db_name: str) -> None:
        self.db_name = db_name
        self.connection = None
        self.cursor = None
        self.connect()

    def __del__(self):
        self.disconnect()

    def connect(self) -> None:
        """
        连接数据库
        :return:
        """
        # 连接到数据库(如果不存在则创建)
        self.connection = sqlite3.connect(self.db_name)
        self.cursor = self.connection.cursor()

    def disconnect(self):
        # 关闭游标和连接
        if self.cursor:
            self.cursor.close()
        if self.connection:
            self.connection.close()

    def execute_create(self, sql):
        """
        创建数据库
        :param sql:
        :return:
        """
        self.cursor.execute(sql)

    def execute_query(self, sql: str, parameters: tuple = None) -> list:
        """
        查询操作
        :param sql: sql语句
        :param parameters: 参数
        :return: 返回结果
        """
        # 执行查询
        if parameters:
            self.cursor.execute(sql, parameters)
        else:
            self.cursor.execute(sql)
        return self.cursor.fetchall()

    def execute_insert(self, sql: str, parameters: tuple = None) -> int:
        """
        插入操作
        :param sql: sql语句
        :param parameters: 参数
        :return: 返回结果
        """
        if parameters:
            self.cursor.execute(sql, parameters)
        else:
            self.cursor.execute(sql)
        self.connection.commit()
        # 返回插入的行的ID
        return self.cursor.lastrowid

    def execute_update(self, sql: str, parameters: tuple = None) -> int:
        """
        更新操作
        :param sql: sql语句
        :param parameters: 参数
        :return: 返回结果
        """
        if parameters:
            self.cursor.execute(sql, parameters)
        else:
            self.cursor.execute(sql)
        self.connection.commit()
        # 返回受影响的行
        return self.cursor.rowcount

    def execute_delete(self, sql: str, parameters: tuple = None) -> int:
        """
        删除操作
        :param sql: sql语句
        :param parameters: 参数
        :return: 返回结果
        """
        if parameters:
            self.cursor.execute(sql, parameters)
        else:
            self.cursor.execute(sql)
        self.connection.commit()
        # 返回受影响的行
        return self.cursor.rowcount
3.1 创建数据库和表
# 创建工具类实例
db = SQLite3Tools('test.db')
# 第一次使用需要创建一个表
db.execute_create('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
3.2 插入数据
db = SQLite3Tools('test.db')
# 执行插入
user_id = db.execute_insert("INSERT INTO users (name, age) VALUES (?, ?)", ('张三', 18))
print(f"张三的id为: {user_id}")
user_id = db.execute_insert("INSERT INTO users (name, age) VALUES (?, ?)", ('李四', 19))
print(f"李四的id为: {user_id}")
user_id = db.execute_insert("INSERT INTO users (name, age) VALUES (?, ?)", ('王五', 19))
print(f"王五的id为: {user_id}")

# 张三的id为: 1
# 李四的id为: 2
# 王五的id为: 3
3.3 查询数据
db = SQLite3Tools('test.db')
# 执行查询
result = db.execute_query("SELECT * FROM users")
print(result)

# [(1, '张三', 18), (2, '李四', 19), (3, '王五', 19)]
3.4 更新数据

将张三的年龄更新为30岁

db = SQLite3Tools('test.db')
# 执行更新
result = db.execute_update("UPDATE users SET age = ? WHERE name = ?", (30, '张三'))
print(f"受影响的行:{result}")

# 受影响的行:1
3.5 删除数据

删除id为4的数据(不存在的一个数据)

db = SQLite3Tools('test.db')
# 删除一个不存在的数据
result = db.execute_delete("DELETE FROM users WHERE id = ?", (4,))
print(f"受影响的行:{result}")

# 受影响的行:0

删除id为3的数据(该数据存在)

db = SQLite3Tools('test.db')
# 删除一个存在的数据
result = db.execute_delete("DELETE FROM users WHERE id = ?", (3,))
print(f"受影响的行:{result}")

# 受影响的行:1

✏ 总结

SQLite是一种轻量级的、零配置的、自包含的、开源的关系型数据库引擎。它提供了一个简单而方便的方式来存储和管理数据。
使用场景:

  • 桌面应用程序:sqlite3可以作为桌面应用程序的本地数据库,用于存储用户设置、缓存数据等;
  • 移动应用程序:sqlite3在Android和iOS平台上都有广泛的使用,可以作为移动应用程序的本地数据库,存储离线数据、用户信息等;
  • 小型项目:对于一些简单的项目,可以使用sqlite3作为数据库解决方案,避免了复杂的数据库配置和维护工作;
  • 学习和测试:sqlite3是一个很好的学习关系型数据库的工具,可以帮助初学者快速了解数据库的基本概念和操作。

💖 欢迎关注我的公众号

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

antd的表格组件错乱问题

环境 react&#xff1a;17.0.2 antd&#xff1a;3.26.20 问题 表格头列宽度和表格体列宽度不一致&#xff0c;表格错乱 解决 针对这个问题官方github仓库里面有专门的issues https://github.com/ant-design/ant-design/issues/13825 里面给出了几种解决方案&#xff1a…

31、matlab卷积运算:卷积运算、二维卷积、N维卷积

1、conv 卷积和多项式乘法 语法 语法1&#xff1a;w conv(u,v) 返回向量 u 和 v 的卷积。 语法2&#xff1a;w conv(u,v,shape) 返回如 shape 指定的卷积的分段。 参数 u,v — 输入向量 shape — 卷积的分段 full (默认) | same | valid full&#xff1a;全卷积 ‘same…

Compose 可组合项 - DatePicker、DatePickerDialog

一、概念 一般是以对话框的形式呼出&#xff0c;DatePickerDialog 就是对 DatePicker 的一个简单对话框封装。 Composable fun DatePicker( state: DatePickerState, modifier: Modifier Modifier, dateFormatter: DatePickerFormatter remember { DatePickerFor…

15.编写自动化测试(下)

标题 三、控制测试流程3.1 添加测试参数3.2 并行或连续运行测试3.3 显示函数输出3.4 指定/过滤测试用例名称3.5 忽略某些测试用例3.6 只运行被忽略的测试 四、测试的组织结构4.1 概念引入4.2 测试私有函数4.2 单元测试4.3 集成测试4.4 集成测试中的子模块4.5 二进制crate的集成…

【漏洞复现】畅捷通T+ keyEdit SQL注入漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

Confluence安装

Confluence安装 1.安装 #下载confluence版本&#xff08;8.5.11&#xff09; https://www.atlassian.com/software/confluence/download-archives #修改权限 chmod x atlassian-confluence-8.5.11-x64.bin #执行安装 ./atlassian-confluence-8.5.11-x64.bin按照以下提示输入&…

SD-WAN在教育行业的应用及优势解析

随着教育领域的数字化转型&#xff0c;网络技术的需求变得愈发迫切。作为一种前沿的网络解决方案&#xff0c;SD-WAN正在为教育行业提供强有力的支持。本文将详细探讨SD-WAN在教育行业的应用&#xff0c;并分析其为教育行业带来的众多优势。 实现多校区高效互联 教育机构通常拥…

稳了?L3规模化落地在即,激光雷达公司成首批赢家

作者 | 芦苇 编辑 | 德新 在中国&#xff0c;距L3级自动驾驶的规模化落地&#xff0c;又近了一步。 随着国内试点政策刷新&#xff0c;越来越多的车企在部分市域获得了自动驾驶测试牌照&#xff0c;能上路测试的L3级自动驾驶车辆正在快速增加。 其中一个重要节点是&#xf…

Python基础用法 之 转义字符

将两个字符进⾏转义 表示⼀个特殊的字符 \n ---> 换⾏&#xff0c;回⻋ \t ---> 制表符, tab键 注意&#xff1a; print( end\n)&#xff1a; print() 函数中默认有⼀个 end\n, 所以,每个 print 结束之后, 都会输出⼀ 个换行。 未完待续。

Java数据类型及运算符及数组(与C语言对比)

Java和C语言在数据类型大部分相同&#xff0c;但是也有不同 1.新增了byte类型&#xff08;相当于C语言中把char用作整数一样&#xff09; 2.然后就是char类型的大小改为了2字节。 3.布尔型改名为boolean而不是bool,且大小没有明确规定&#xff0c;方便进行不同平台之间的移…

使用dev_dbg调试

首先内核要使能两个配置才可以使用。一般内核都是打开的。 CONFIG_DEBUG_FSy CONFIG_DYNAMIC_DEBUGy 当编译选项CONFIG_DYNAMIC_DEBUG打开的时候&#xff0c;在编译阶段&#xff0c;kernel会把所有使用dev_dbg()的信息记录在一个table中&#xff0c;这些信息我们可以从/sys/k…

在线预览多类型文件_全栈

目录 一、下载运行项目 二、项目功能 三、前端项目引用 四、文件预览样式更改 在做项目时经常用到在线预览文件&#xff0c;给大家介绍一个好用的在线预览文件项目。使用技术是后端Java&#xff0c;前端Freemarker模板。 FreeMarker 特别适应与 MVC 模式的 Web 应用&#x…

从“产品的RFM分析”看如何探索“职业方向”

我们在做产品分析时&#xff0c;经常会用到一种方法“产品的RFM分析”&#xff0c;它是一种客户细分和价值评估的常用方法&#xff0c;广泛应用于电子商务、零售和其他众多行业&#xff0c;它可以帮助企业和产品团队更好地理解用户行为&#xff0c;优化营销策略&#xff0c;提升…

解禁日大涨,爱玛科技的投资前景值得信任吗?

6月17日&#xff0c;爱玛迎来6.28亿股、金额超190亿元的解禁&#xff0c;占总股本72.91%。不过&#xff0c;爱玛股价在巨量解禁中反而迎来涨势&#xff0c;因为这部分股票中&#xff0c;创始人张剑持有的限售股数量几乎就占了爱玛总股本的七成。某种意义上&#xff0c;市场认为…

【产品经理】订单处理4-拆单策略

上次讲解了订单的促销策略&#xff0c;本次讲解下订单处理过程中的拆单策略。 订单拆单策略分为自动拆单、手动拆单&#xff0c;拆单时机也分为订单未被审核前拆单、订单审核后因仓库/快递情况的拆单&#xff0c;本次主要讲解订单未被审核前拆单、订单审核后快递超重的拆单&am…

ollama模型CPU轻量化部署

一、定义 ollama 定义环境部署demo加载本地模型方法基本指令关闭开启ollamaollama 如何同时 运行多个模型, 多进程ollama 如何分配gpu修改模型的存储路径 二、实现 ollama 定义 ollama 是llama-cpp 的进一步封装&#xff0c;更加简单易用&#xff0c;类似于docker. 模型网址…

SFNC —— 标准特征命名约定(一)

系列文章目录 SFNC —— 标准特征命名约定&#xff08;一&#xff09; 文章目录 系列文章目录1、介绍1.1 约定&#xff08;Conventions&#xff09;功能名称和接口&#xff08;Feature Name and Interface&#xff09;功能类别&#xff08;Feature Category&#xff09;功能级别…

菜单栏(骆驼书)

代码如下&#xff1a; 效果图&#xff1a;

使用宝塔面板部署Django应用(不成功Kill Me!)

使用宝塔面板部署Django应用 文章目录 使用宝塔面板部署Django应用 本地操作宝塔面板部署可能部署失败的情况 本地操作 备份数据库 # 备份数据库 mysqldump -u root -p blog > blog.sql创建requirements # 创建requirements.txt pip freeze > requirements.txt将本项目…

揭示SOCKS5代理服务器列表的重要性

在复杂的网络安全领域中&#xff0c;SOCKS5代理在保护在线活动方面发挥着关键作用。本文深入探讨了SOCKS5代理服务器列表的细节&#xff0c;探讨了它们的应用、优势以及在增强在线安全和隐私方面不可或缺的功能。 一、理解SOCKS5代理服务器列表 作为在客户端和服务器之间进行通…