【学库】TinyDB(进阶)——让你开心的面向文档的微型数据库

TinyDB(Query())

数据存储格式

1、默认使用JSON格式,只能处理简单类型的数据,自定义类肯定搞不定。

2、如果出现了问题,可以自己写存储格式,可以变得更强大但是也更慢。

提示:如果多个TinyDB打开了同一个数据源(json文件),在用Query()查询是会意外。

 1、ORM语法

开始不太懂,自己查了下:

ORM:对象关系映射(Object Relational Mapping,简称ORM),
目的是想像操作对象一样操作数据库.因为数据库不是面向对象的,所以需要编程进行映射.

1.1 基本操作

这里要使用上一节代码跑完后生成的  db.json 文件。

前提条件是:实例化一个TinyDB()对象 db = TinyDB('db.json') 和一个Query()对象 User = Query() 

db = TinyDB('db.json')
User = Query()
a = db.search(User.name == 'John')
print(a) # [{'name': 'John', 'age': 22}]

因为在上一节不小心跑了两遍insert(),所以相当于添加了两次  {'name': 'John', 'age': 22} 。这个入门里面已经讲了,记得代码里面还可用中文。

1.2 嵌套查询

如果字典里面key对应的value也是字典怎么办?这种情况应该还是蛮常见的。

db.insert({'湖北':{'宜昌':'0717'}})  # 新增一个这种情况
b = db.search(User.湖北.宜昌 == '0717') # 嵌套就是继续在后面加'.'
print(b) # [{'湖北': {'宜昌': '0717'}}] 

1.3 特殊情况

如果要查询的键里面含有python解释器不能当成映射的符号怎么办?比如: + - * / % 

db.insert({'1+1':'2'})
c = db.search(User['1+1'] == '2') 那就只能用这种方法,
print(c) #[{'1+1': '2'}]

1.4 where方法

这是一种简化的方法,先看代码:

from tinydb import where  # 要先导入where
d = db.search(where('name')=='John')
e = db.search(Query()['name']=='John')
print(d) # [{'name': 'John', 'age': 22}]
print(e) # [{'name': 'John', 'age': 22}]

发现这两个东西结果是一样的。结果代码导航后一看,源码里面赫然写着:

def where(key):
  return Query()[key]

它就是这么写的,按照这个思路,还可以再扩展下。我如果想直接拿到具体的文字,而不是查询所返回的列表:

from tinydb import TinyDB, where

db = TinyDB('test.json')
db.insert({'名字':'张三','分数':'100'})
db.insert({'名字':'李四','分数':'98'})

def get_data(db,index_a, val, index_b ):
    print(db.search(where(index_a)== val)[0][index_b]) #这个[0]不能少

get_data(db,'名字', '张三', '分数') # 100
get_data(db,'分数', '100', '名字') # 张三

扯远了,刚才往后翻了下,居然真的还有个TinyDB自带的类似方法:  db.get(...) 。后面再讲,它有特定的使用条件。

 Query() 有嵌套,那说明 where() 应该也有嵌套,毕竟 where(key) = Query()[key] 

#使用where()对字段进行嵌套查询
db.insert({'birthday':{'year':1999,'month':'Sep','day': 11}})
f = db.search(where('birthday').year == 1999)
g = db.search(where('birthday')['year'] == 1999)
print(f) # [{'birthday': {'year': 1999, 'month': 'Sep', 'day': 11}}]
print(g) # [{'birthday': {'year': 1999, 'month': 'Sep', 'day': 11}}]

上面两种方式都可以。

2、高级查询

2.1 判断是否存在【.exisets()】,返回对于字段列表(filed)

h = db.search(User.name.exists())
print(h) # [{'name': 'John', 'age': 22}, {'name': 'sheet', 'age': 23}]

2.2 正则表达式判断【.matches( )】

i = db.search(User.name.matches('[aZ]*'))
print(i) # [{'name': 'John', 'age': 22}, {'name': 'sheet', 'age': 23}]

但是我的正则学的不好,早就忘记了,没关系,还有更屌的!

import re
j = db.search(User.name.matches('John', flags=re.IGNORECASE))
print(j)  # [{'name': 'John', 'age': 22}]

直接用value值‘John’去匹配他的key,也就是'name'。

那如果value值很长,记不准怎么办?

没关系,还支持使用首字符查询。首字符可以,前n个字符都可以,中间的切片不行。

那如果value值是个字典,怎么办?

没关系,还支持使用嵌套的方法。

db.insert({'中国':'湖北省','武汉':{'继续':'加油'}})
l = db.search(User.中国.matches('湖北', flags=re.IGNORECASE))
l_1 = db.search(User.中国.matches('', flags=re.IGNORECASE))
l_2 = db.search(User.中国.matches('', flags=re.IGNORECASE))
# value也是字典的话,只能嵌套查询
m = db.search(User.武汉.matches('加油', flags=re.IGNORECASE)) 
n = db.search(User.武汉.继续.matches('', flags=re.IGNORECASE))
print(l) #[{'中国': '湖北省', '武汉': {'继续': '加油'}}]
print(l_1) #[{'中国': '湖北省', '武汉': {'继续': '加油'}}]
print(l_2) # []
print(m) # []
print(n) # [{'中国': '湖北省', '武汉': {'继续': '加油'}}]

我觉得这个就有点太NB了。

2.3 自定义查询【.test()】

自己可以写一段用来判断的函数,直接作为判断条件进行使用。分带参数和不带参数两种。

test_func = lambda s:s == 'John'
o = db.search(User.name.test(test_func))
print(o) # [{'name': 'John', 'age': 22}]
# 带参数
def test_func1(val, m, n):
    return m <= val <= n
p = db.search(User.age.test(test_func1,2,40))
print(p) #[{'name': 'John', 'age': 22}, {'name': 'sheet', 'age': 23}]

猜你喜欢

转载自www.cnblogs.com/watalo/p/12388046.html
今日推荐