【Python】TinyDB:轻量文档数据库
TinyDB 是一个轻量级的文档数据库,以JSON格式存储数据,主要适用于小型项目或嵌入式系统。TinyDB的主要特点是无模式(schema-less)、纯Python实现、简单易用。TinyDB支持灵活的查询操作,可以对数据进行增删改查等操作,是一个学习数据库的极佳工具。
安装TinyDB
首先需要安装TinyDB,可以使用pip
命令来完成安装:
pip install tinydb
安装完成后,即可在代码中引入TinyDB
和其他相关模块。
初始化数据库和表
在TinyDB中,所有数据都存储在JSON文件中。数据库的初始化步骤如下:
from tinydb import TinyDB, Query
# 创建或打开一个JSON文件作为数据库
db = TinyDB('db.json')
这段代码会在当前目录下创建一个名为db.json
的文件,所有数据将被保存到此文件中。
数据表概念
TinyDB中默认会使用一张主表(主表名为_default
),也可以通过创建自定义表来分类存储不同类型的数据。例如:
# 创建或选择一个名为 'users' 的表
users_table = db.table('users')
通过table()
方法可以方便地管理多张表,使用 db.drop_table(...)
删除表,或 db.tables()
获取所有表名。
数据操作
插入数据
您可以使用 db.insert(...)
或 db.insert_multiple(...)
来插入单个或多个文档,并可以使用 Document
类来指定文档ID:
from tinydb import Document
# 在默认表中插入一条文档ID为12的数据
db.insert(Document({
'name': 'John', 'age': 22}, doc_id=12))
# 插入多条数据
db.insert_multiple([
{
'name': 'Bob', 'age': 30, 'city': 'Los Angeles'},
{
'name': 'Charlie', 'age': 22, 'city': 'Chicago'}
])
更新数据
使用 db.update(...)
可更新文档。例如,删除字段:
from tinydb.operations import delete
db.update(delete('key1'), User.name == 'John')
还支持增量更新:
from tinydb.operations import increment
db.update(increment('age'), User.name == 'John')
Upsert(更新或插入)
db.upsert(...)
用于在查询匹配时更新文档,否则插入新文档:
db.upsert({
'name': 'John', 'logged-in': True}, User.name == 'John')
数据检索
您可以使用 db.get(...)
获取单个文档,db.contains(...)
检查数据库中是否包含匹配项,或 db.count(...)
获取匹配项的数量。
数据查询
ORM风格查询
TinyDB提供类似ORM的查询方式。通过 Query
类创建查询对象,然后使用该对象来定义查询条件。例如:
from tinydb import Query
User = Query()
db.search(User.name == 'John')
通过这种方式,您可以轻松查询嵌套字段。例如:
db.search(User.birthday.year == 1990)
对于不符合Python标识符的字段(例如带有特殊字符的字段名),可以通过字典访问方式:
db.search(User['country-code'] == 'foo')
您还可以在字段位置使用自定义转换函数:
from unidecode import unidecode
db.search(User.name.map(unidecode) == 'Jose') # 匹配 'José'
传统风格查询
另一种方式是使用 where
函数:
from tinydb import where
db.search(where('field') == 'value')
嵌套字段的访问方式如下:
db.search(where('birthday').year == 1900)
db.search(where('birthday')['year'] == 1900)
字段存在
db.search(User.name.exists())
正则表达式匹配
支持全匹配和部分匹配,例:
db.search(User.name.matches('[aZ]*'))
db.search(User.name.search('b+'))
还支持带参数的自定义测试函数:
test_func = lambda s: s == 'John'
db.search(User.name.test(test_func))
def test_func(val, m, n):
return m <= val <= n
db.search(User.age.test(test_func, 0, 21))
片段搜索
可以使用 .fragment
方法搜索与片段字典匹配的文档:
db.search(Query().fragment({
'foo': True, 'bar': False}))
对于嵌套字段的片段匹配:
db.search(Query().field.fragment({
'foo': True, 'bar': False}))
列表字段查询
TinyDB提供了 .any()
和 .all()
方法,用于匹配列表字段。例如,以下代码检查字段是否至少包含一个给定值:
db.search(User.groups.any(['admin', 'sudo']))
对于嵌套查询:
groups.search(Group.permissions.any(Permission.type == 'read'))
查询操作符
TinyDB支持逻辑操作符,可以结合查询条件:
# 逻辑非
db.search(~(User.name == 'John'))
# 逻辑与
db.search((User.name == 'John') & (User.age <= 30))
# 逻辑或
db.search((User.name == 'John') | (User.name == 'Bob'))
使用文档ID
TinyDB为每个文档分配一个ID,可用于快速访问:
# 获取ID
el = db.get(User.name == 'John')
print(el.doc_id)
# 通过ID更新
db.update({
'value': 2}, doc_ids=[1, 2])
数据删除
TinyDB提供了remove()
方法来删除符合条件的数据。可以通过特定条件删除单条或多条记录。
删除单条记录
删除name
为Charlie
的用户:
db.remove(User.name == 'Charlie')
清空表
如果要清空表中所有记录,可以使用truncate()
方法:
db.truncate() # 清空表中的所有数据
数据统计与管理
TinyDB提供了简单的统计方法来辅助数据管理。
数据统计
可以使用len()
函数获取表中的记录数:
record_count = len(db)
print("记录数量:", record_count)
条件计数
可以通过count()
方法统计符合条件的记录数:
# 统计年龄大于25的用户数量
count = db.count(User.age > 25)
print("符合条件的记录数量:", count)
多表管理与分表存储
TinyDB允许在同一数据库文件中创建多个表,可以通过table()
方法创建不同的表。
# 创建 'products' 表并插入数据
products_table = db.table('products')
products_table.insert({
'name': 'Laptop', 'price': 1200})
可以通过多表存储不同类型的数据,例如用户数据存放在users
表中,产品数据存放在products
表中。
自定义存储
TinyDB支持自定义存储器。如果需要将数据存储到不同的文件中,或者使用自定义格式,可以使用Storage
类创建自定义存储。举例来说,可以创建一个基于内存的存储。
基于内存的存储
from tinydb.storages import MemoryStorage
# 使用内存存储数据库
db = TinyDB(storage=MemoryStorage)
db.insert({
'name': 'In-Memory User', 'age': 20})
print(db.all())
这种方式在数据量较小时非常有效,但关闭程序后数据会丢失。
总结
通过本教程,我们学习了如何使用TinyDB的所有常用功能,从基本的增删改查操作到高级查询和多表管理。TinyDB提供了简洁的JSON格式存储,可以直接打开数据库文件查看内容,非常适合小型项目和数据量不大的应用。希望本教程可以帮助你深入掌握TinyDB的用法,让你的项目中轻松实现数据存储和管理。