Package: unqdantic
UnqDantic基于 UnQLite 的嵌入式数据库 ODM简介UnqDantic 是一个基于UnQLite和Pydantic的 Python 对象文档映射器(ODM)。基于 UnQLite 的轻量、嵌入式特性，你可以在单文件或者内存中使用 NoSQL 数据库，就像 mongodb 一样！得益于 Pydantic 的模型和数据验证，你可以轻松的构建一个文档模型，非常简单高效地创建和查询数据！在简单的场景下，它完全可以替代复杂的 mongodb，让你更加高效方便地存储 JSON 文档数据。不要再用 json 文件当数据库用啦，来试试 UnqDantic 吧！！但是 UnQLite 不支持索引、唯一约束等特性，尚未知性能如何，可能不适用于大型项目安装注意，本库还在开发中，后续可能会有 breaking change，谨慎使用使用 pip:pip install unqdantic使用 Poetry:poetry add unqdantic使用 PDM:pdm add unqdantic示例fromtypingimportAny,Dict,List,OptionalfromunqdanticimportDatabase,DocumentfrompydanticimportField,BaseModel# 像pydantic一样定义模型，可以使用pydantic的所有特性# 定义内嵌模型classUserInfo(BaseModel):money:int=100level:int=1# 定义文档模型classUser(Document):name:strage:intinfo:UserInfo=Field(default_factory=UserInfo)classMeta:name:str="user"# 指定文档的集合名，否则默认为类名的小写db:Database# 可传入要绑定的数据库对象，或者在数据库初始化时传入本模型来绑定# db = Database(filename=":mem:", documents=[User])by_alias:bool=False# 是否在数据库集合中使用字段别名，同pydantic# 初始化unqlite数据库# filename中，:mem:代表在内存中使用，也可以传入文件路径# documents为要绑定的文档模型，数据库会自动为模型创建同名的集合db=Database(filename=":mem:",documents=[User])# db = Database(filename=pathlib.Path("my_data.db"), documents=[User])# 使用Pydantic式创建文档对象，调用insert()来插入文档user1=User(name="a",age=15).insert()# 更新模型对象的属性，并更新到数据库user1.update(fields={User.age:20,User.info.money:150,},)# 也可以用关键字参数形式更新user1.update(age=20)# 还可以手动修改后，调用save()来更新到数据库user1.info.level=2user1.save()# 如果没有name为a且age为15的文档，则创建，否则更新info.level为2user2=User.update_or_create(User.name=="a",User.age==20,defaults={User.info.level:2,},)# 这两个模型为同一个文档，id一致assertuser1.id==user2.id# 删除该文档user2.delete()# 可以先创建模型对象，然后使用save_all批量插入到数据库user3=User(name="b",age=18,info=UserInfo(money=150))user4=User(name="c",age=25,info=UserInfo(money=200,level=20))User.save_all(user3,user4)# 如果没有name为d的文档，则使用defaults中的数据创建它，否则获取它user5=User.get_or_create(User.name=="d",defaults={User.age:15,User.info.level:10,},)# 根据主键id查询文档user:Optional[User]=User.get_by_id(id=0)# 根据主键id删除文档delete_result:bool=User.delete_by_id(id=0)# 查询满足所有条件的文档users:List[User]=User.find_all(User.age==18,User.info.money>=150)# 查询满足任一条件的文档users:List[User]=User.find_all((User.age<=18)|(User.info.level>=2))# 查询满足条件的首个文档，如无则返回Noneuser:Optional[User]=User.find_one(User.age>=18)# 取出所有文档all_users:List[User]=User.all()# 导出所有文档为dict对象user_dicts:List[Dict[str,Any]]=User.export_all_to_dict()# 从Dict对象列表批量保存文档users:List[User]=User.bulk_save_from_dict(user_dicts)# 清空所有文档User.clear()# 如果你不想使用文档模型，也可以直接操作集合fromunqdanticimportCollection# 需要传入数据库对象和集合名collection=Collection(db=db,name="custom_collection")# 可以存放任意dict或List[dict]，但是要注意：# 值只支持str、int、float、bool等基本数据类型，复杂类型可能会被存为None# 返回结果为最后一个文档的主键idid:int=collection.store({"key":"value"})id:int=collection.store([{"name":"a"},{"name":"b","age":18}])# 获取指定id的文档data:Optional[Dict[str,Any]]=collection.fetch(id=id)# 更新指定id的文档# 注意，它不等于dict.update，它是完全替换旧的文档内容collection.update(id=id,data={"key":"value2"})# 删除文档collection.delete(id=id)# 可以过滤查询文档# 需要传入一个参数为文档，返回值为bool的函数datas:Optional[List[Dict[str,Any]]]=collection.filter(lambdadoc:doc["name"]=="a")# 除此之外，你还可以直接将数据库db当键值对数据库使用，就像python的dict一样# 但是同样的，值只支持基本数据类型，并且返回值是该值的bytes形式# 存一个键值对db["key"]="value"# 取出值value:Optional[bytes]=db["key"]# b"value"# 删除值deldb["key"]# 查看键值对是否存在assert"key"notindb后续计划允许自定义encoder、decoder复杂的事务支持Async IO 支持(也许不会)鸣谢UnQLite: 本项目的基础， C 语言编写的嵌入式 NoSQL 文档数据库unqlite-python：本项目的基础，unqlite 的 python bindingPydantic: 本项目的基础，数据模型检验库mango: odm 代码参考