[python] 基于Dataset库操作数据库
dataset库是Python中一个用于操作数据库的简单库,它提供了一种简洁的方式与各种关系型数据库进行交互,例如SQLite、MySQL、PostgreSQL 等。你可以使用dataset库来执行查询、插入、更新和删除操作,而无需编写复杂的SQL语句。dataset库适用于小规模的数据存储和查询场景,相比csv和json文件只能通过编程语言来处理数据,dataset支持使用SQL语言进行查询,提供了丰富的查询功能和灵活性。对于大规模数据和高并发场景,专业数据库系统如MySQL、PostgreSQL等更具优势。
dataset官方仓库地址:dataset。dataset官方文档地址:dataset-doc。安装命令如下:
pip install dataset
import dataset
# 查看版本
dataset.__version__
'1.6.2'
1 使用说明
1.1 数据库操作
数据库创建
connect函数是dataset库中用于连接到数据库并返回一个数据库对象。它的使用方式如下:
# 创建一个连接到名为mydatabase.db的SQLite数据库的对象
# 如果要连接的数据库不存在,则自动创建
db = dataset.connect('sqlite:///mydatabase.db')
# 如果要连接到MySQL数据库(需要安装相应组件),可以使用以下语法:
# db = dataset.connect('mysql://user:password@localhost/mydatabase')
# 如果要连接到PostgreSQL数据库(需要安装相应组件),可以使用以下语法:
# db = dataset.connect('postgresql://user:password@localhost/mydatabase')
表格查询与创建
dataset提供get_table函数或直接表名索引来创建或加载一个表格。同时,dataset也提供create_table函数创建一个新的表格,也可以使用load_table函数加载现有的表格。
# 使用db['table_name']语法获取指定表的引用,其中table_name是表的名称
# 如果表不存在,dataset库将自动创建它,但是只有数据插入才会保存
table = db['mytable']
# 或者使用如下函数:
# table = db.get_table('mytable')
# 创建一个新表格,原有表格会被覆盖
# 该表没有自定义的主键或类型。Dataset库会默认创建一个名为 'id' 的整数类型的主键。
table = db.create_table('mytable')
此外也可以指定表格创建时的各种参数,dataset主要支持类型有:
- db.types.integer:表示整数类型。
- db.types.float:表示浮点数类型。
- db.types.boolean:表示布尔类型。
- db.types.datetime:表示日期时间类型。
- db.types.date:表示日期类型。
- db.types.text:表示文本字符串类型。
# 指定了自定义主键为 'age'
# db.create_table('mytable', 'age')
# 指定了自定义的主键为 'city',并且指定该主键的类型为文本类型
# db.create_table('mytable', primary_id='city', primary_type=db.types.text)
# 指定没有主键
# db.create_table('mytable', primary_id=False)
# 加载现有表格
table = db.load_table('mytable')
# 如果表格不存在,则会报错
# table = db.load_table('user')
# 也可以通过has_table函数查询是否存在某个表
db.has_table('user')
False
# 查看当前数据库下所有表格
db.tables
[]
直接在数据库上运行sql查询语句
dataset库提供query函数用于过滤和查询数据集。它接受一个字符串参数,该参数表示一条 SQL 查询语句,用于选择符合条件的数据。
# statement = 'SELECT * FROM mytable'
# for row in db.query(statement):
# print(row)
1.2 表格操作
插入数据
# 使用db['table_name']语法获取指定表的引用,其中table_name是表的名称
# 如果表不存在,dataset库将自动创建它
table = db['mytable']
insert用于插入数据。
# 插入一条包含名字、年龄和电子邮件的记录
data = {'name': 'John', 'age': 25, 'email': 'john@example.com'}
table.insert(data)
# 插入一条包含名字、年龄,电子邮件的记录为空
table.insert(dict(name='Alice', age=25))
2
insert_ignore用于插入一行数据,但只有在keys中列的值不重复时才会插入。
table.insert_ignore(dict(name='Alice', age=25),keys=['name'])
False
insert_many函数用于向数据库表中批量插入数据。它接受一个列表作为参数,该列表中的每个元素都是一个字典,表示要插入的一行数据。使用该函数要比逐个添加快很多。
data = [
{'name': 'John', 'age': 25, 'city': 'New York'},
{'name': 'Alice', 'age': 30, 'city': 'Los Angeles'},
{'name': 'Bob', 'age': 35, 'city': 'San Francisco'}
]
table.insert_many(data)
插入列
# 插入名为 key 的列,数据类型为文本(text),并且设置了唯一约束(unique=True)
# table.create_column('key', db.types.text,unique=True)
# 插入名为 food 的列,数据类型为文本(text)
table.create_column('food', db.types.text)
# 创建一个列,第一个值为列名,第二个值用于自动猜测该列的类型
table.create_column_by_example('length', 4.2)
查看数据
# 查看表格行数
len(table)
5
# 获取表中的所有数据
data = list(table.all())
# 打印数据
for row in data:
print(row)
OrderedDict([('id', 1), ('name', 'John'), ('age', 25), ('email', 'john@example.com'), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 2), ('name', 'Alice'), ('age', 25), ('email', None), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 3), ('name', 'John'), ('age', 25), ('email', None), ('city', 'New York'), ('food', None), ('length', None)])
OrderedDict([('id', 4), ('name', 'Alice'), ('age', 30), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
OrderedDict([('id', 5), ('name', 'Bob'), ('age', 35), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
# 直接打印数据
for row in table:
print(row)
OrderedDict([('id', 1), ('name', 'John'), ('age', 25), ('email', 'john@example.com'), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 2), ('name', 'Alice'), ('age', 25), ('email', None), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 3), ('name', 'John'), ('age', 25), ('email', None), ('city', 'New York'), ('food', None), ('length', None)])
OrderedDict([('id', 4), ('name', 'Alice'), ('age', 30), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
OrderedDict([('id', 5), ('name', 'Bob'), ('age', 35), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
# 表的列名
table.columns
['id', 'name', 'age', 'email', 'city', 'food', 'length']
# 是否存在某列
table.has_column('sex')
False
查找数据
# 根据字段查找
results = table.find(name='John')
# 遍历结果
for row in results:
print(row['name'], row['city'])
John None
John New York
# 多字段查找
results = table.find(name='John',city=None)
# 遍历结果
for row in results:
print(row['name'], row['city'])
John None
# 仅返回第一个结果
results = table.find_one(name='John')
results
OrderedDict([('id', 1),
('name', 'John'),
('age', 25),
('email', 'john@example.com'),
('city', None),
('food', None),
('length', None)])
# 基于id查询
results = table.find(id=[1, 2, 4])
# 遍历结果
for row in results:
print(row['name'], row['city'])
John None
Alice None
Alice Los Angeles
# 找出age大于等于30的结果
results = table.find(age={'>=': 30})
for row in results:
print(row['name'], row['age'])
Alice 30
Bob 35
# 找出age在21到30之间的结果
results = table.find(age={'between': [21, 30]})
for row in results:
print(row['name'], row['age'])
John 25
Alice 25
John 25
Alice 30
# 筛选某个字段下的唯一项
results = table.distinct('name')
for row in results:
print(row)
OrderedDict([('name', 'Alice')])
OrderedDict([('name', 'Bob')])
OrderedDict([('name', 'John')])
dataset库还支持更丰富的查询操作,具体可以查看文档:dataset-query。
更新数据
update函数用于更新单条记录。
# 第一参数为要更新的字段和对应的新值,如果字段不存在则会添加该字段
# 第二个参数keys用于指定根据哪些列来筛选要更新的对象
# 下面代码表示将name为'John'的行更新数据
affected_rows = table.update(dict(name= 'John',age=23,email="qq.com"), keys=['name'])
print("受影响的行数:", affected_rows)
受影响的行数: 2
# 获取表中的所有数据
data = list(table.all())
# 打印数据
for row in data:
print(row)
OrderedDict([('id', 1), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 2), ('name', 'Alice'), ('age', 25), ('email', None), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 3), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', 'New York'), ('food', None), ('length', None)])
OrderedDict([('id', 4), ('name', 'Alice'), ('age', 30), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
OrderedDict([('id', 5), ('name', 'Bob'), ('age', 35), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
update_many也被提供用于批量更新数据。
# 更新多行数据
rows = [
{'name': 'Alice', 'age': 123},
{'name': 'Bob', 'age': 18}
]
# 该函数没有返回值
table.update_many(rows,keys=['name'])
此外也可以用upsert和upsert_many插入更新单条或多条记录,即如果存在具有匹配关键字的行,则这些行将被更新,否则将在表中插入新行。具体使用类似update和update_many。
删除数据
delete函数用于删除行,如下所示:
for row in table:
print(row)
OrderedDict([('id', 1), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 2), ('name', 'Alice'), ('age', 123), ('email', None), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 3), ('name', 'John'), ('age', 23), ('email', 'qq.com'), ('city', 'New York'), ('food', None), ('length', None)])
OrderedDict([('id', 4), ('name', 'Alice'), ('age', 123), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
# 删除age为23的记录
table.delete(age=23)
for row in table:
print(row)
OrderedDict([('id', 2), ('name', 'Alice'), ('age', 123), ('email', None), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 4), ('name', 'Alice'), ('age', 123), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
# 删除age为30且name为'John'的记录
table.delete(age=30, name='John')
for row in table:
print(row)
OrderedDict([('id', 2), ('name', 'Alice'), ('age', 123), ('email', None), ('city', None), ('food', None), ('length', None)])
OrderedDict([('id', 4), ('name', 'Alice'), ('age', 123), ('email', None), ('city', 'Los Angeles'), ('food', None), ('length', None)])
OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
# 找出age大于等于30的结果
table.delete(age={'>=': 30})
for row in table:
print(row)
OrderedDict([('id', 5), ('name', 'Bob'), ('age', 18), ('email', None), ('city', 'San Francisco'), ('food', None), ('length', None)])
drop_column函数会从数据集中删除指定的列,如下所示:
# sqlite不支持
# table.drop_column('age')
# for row in table:
# print(row)
1.3 事务操作
事务是一组数据库操作,要么全部成功执行,要么全部回滚。这可以确保数据的一致性和完整性。下面代码展示了如何创建一个事务对象。在这种情况下,所有更新都会立即提交,或者,在出现异常的情况下,立即回滚所有操作。事务通过上下文管理器得到支持,因此可以通过with语句使用:
with dataset.connect('sqlite:///mydatabase.db') as tx:
# 在这里执行数据库操作
# 如果所有操作都成功,事务会自动提交
# 如果发生错误,事务会自动回滚
tx['user'].insert(dict(name='John Doe', age=46, country='China'))
当然以上代码可以显式调用函数begin、commit和rollback来获得相同的功能:
db = dataset.connect('sqlite:///mydatabase.db')
db.begin()
try:
db['user'].insert(dict(name='John Doe', age=46, country='China'))
db.commit()
except:
db.rollback()
除此之外,也支持嵌套事务如下所示:
db = dataset.connect()
with db as tx1:
tx1['user'].insert(dict(name='John Doe', age=46, country='China'))
with db as tx2:
tx2['user'].insert(dict(name='Jane Doe', age=37, country='France', gender='female'))
2 参考
[python] 基于Dataset库操作数据库的更多相关文章
- [python] 基于paramiko库操作远程服务器
SSH(Secure Shell)是一种网络安全协议,能够使两台计算机安全地通信和共享数据.目前,SSH协议已在世界各地广泛使用,大多数设备都支持SSH功能.SSH的进一步说明见:深入了解SSH.SS ...
- Python 3 mysql 库操作
Python 3 mysql 库操作 一.基础相关知识 MySQL数据库基本操作知识储备 数据库服务器:一台计算机(对内存要求比较高) 数据库管理系统:如mysql,是一个软件 数据库:oldboy_ ...
- 使用python简单连接并操作数据库
python中连接并操作数据库 图示操作流程 一.使用的完整流程 # 1. 导入模块 from pymysql import connect # 2. 创建和数据库服务器的连接,自行设置 服务器地址, ...
- python如何用sqlalchemy操作数据库
工具:mysql python sqlalchemy ---------------------------------------- 准备工作: 1.安装mysql 如果是window环境请参考 ...
- python学习笔记:操作数据库
1.下载安装模块 第一种:cmd下:执行命令下载安装:pip3 install pymysql 第二种:IDE下pycharm python环境路径下添加模块 2.连接数据库 import pymys ...
- 分享一个以前写的基于C#语言操作数据库的小框架
一:前言 这个是以前写的操作MySQL数据库的小型框架,如果是中小型项目用起来也是很不错的,里面提供Filter.ModelPart.Relationship等机制实现操作数据库时的SQL语句的拼接和 ...
- [python] 基于diagrams库绘制系统架构图
Python的Diagrams库允许通过简单的Python代码绘制云系统架构,实现对新的系统架构进行原型设计.Diagrams的官方仓库地址见:diagrams.Diagrams的官方文档和使用示例见 ...
- python面试题库——3数据库和缓存
第三部分 数据库和缓存(46题) 列举常见的关系型数据库和非关系型都有那些? 关系型数据库: Oracle.DB2.Microsoft SQL Server.Microsoft Access.MySQ ...
- python自定义ORM并操作数据库
看这个代码之前先去看上篇文章,理解type的用法及元类的含义: ORM可以代替pymysql,实现将python语义装换为sql语句,简单化 import pymysql ''' metaclass, ...
- [python] 基于wordcloud库绘制词云图
词云Wordcloud是文本数据的一种可视化表示方式.它通过设置不同的字体大小或颜色来表现每个术语的重要性.词云在社交媒体中被广泛使用,因为它能够让读者快速感知最突出的术语.然而,词云的输出结果没有统 ...
随机推荐
- Binary String Copying
Smiling & Weeping ----第一次见你的时候, 在我的心里已经炸成了烟花, 需要用一生来打扫灰炉. 题目链接:Problem - C - Codeforces 题目大意不难,就 ...
- 面霸的自我修养:ThreadLocal专题
王有志,一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 今天是<面霸的自我修养>第5篇文章,我们一起来看看面试中会问到哪些关于ThreadLocal ...
- WorkPress使用BackWPup插件备份后手动还原方法记录
前提 拿到BackWPup插件备份的zip包(下文均以backup.zip来指代).这个是备份包是事先从源WorkPress上备份好的. 环境 OS:Centos7.9 Apache:2.4.6 PH ...
- TCP连接的关键之谜:揭秘三次握手的必要性
TCP 连接建立 当我们浏览网页.发送电子邮件或者进行在线游戏时,我们常常不会想到背后复杂的网络连接过程.然而,正是这些看似不起眼的步骤,确保了我们与服务器之间的稳定通信.其中最重要的步骤之一就是TC ...
- 08-03_阅读flask上下文前夕补充、flask请求上下文、数据库连接池
文章目录 阅读flask上下文前夕补充 01 偏函数 02 __add__的使用 03 chain函数 2 flask请求上下文 1 首先分析请求上下文对象(ctx)创立 2 把请求对象(ctx)添加 ...
- Android项目Library导入的问题整理
Android项目Library导入的问题整理 本来帮助朋友找寻一下android的一些特效的demo,结果找到了一个,朋友试验可以,自己却是在导入项目需要的library的时候总是出问题,真的很是丢 ...
- 【高手训练】【RMQ】奶牛排队
第一题由于过水,就没写awa 大概就是这样了.题意就是求一个最长的区间使得区间的左边是它的最小值,区间右边是他的最大值第一个想法肯定是暴力枚举啦awa但是这个是O(n^3)的,绝对的不可过awa 思考 ...
- 可视化-vscode安装matplotlib工具
可视化工具中,最流行的工具之一是 Matplotlib,它是一个数学绘图库,可以制作简单的图表,如折线图和散点图: 使用pip可以安装Matplotlib: 安装步骤:: 1.在vscode的终端输入 ...
- CF1352D
题目简化和分析: 这题可以直接按照题意进行模拟,当然有些细节需要注意. 翻译的不足:这里的回合指任意一个人吃掉都算,而不是双方一个回合,最后一个人即使不满足也算一个回合. 我们可以采用两个指针模拟两个 ...
- 浅析Redis大Key
一.背景 在京东到家购物车系统中,用户基于门店能够对商品进行加车操作.用户与门店商品使用Redis的Hash类型存储,如下代码块所示.不知细心的你有没有发现,如果单门店加车商品过多,或者门店过多时,此 ...