连接 AI,NebulaGraph Python ORM 项目 Carina 简化 Web 开发

简介: 这是一款神奇的 Python ORM 项目,它简化了 CURD 操作,免去繁琐的查询语句编写,又适用于裸 Python 开发,可与 AI 行业快速集成。

作者:Steam & Hao

本文整理自社区第 7 期会议中 13‘21″ 到 44’11″ 的 Python ORM 的分享,视频见 https://www.bilibili.com/video/BV1s8411N7Cw

在做业务开发时,NebulaGraph Python ORM 项目作者:Sword Elucidator(下文简称:Hao)发现图数据库在某些场景下有比较不错的应用实践,而 NebulaGraph 是他觉得不错、较为先进的一款图数据库产品。在 Hao 的开发过程中,他发现:虽然图数据库被应用在多个业务场景中,但对于像是 App 开发之类的 ISO/OSI 高层实践的话,nebula-python 之类的客户端就略显笨重。

而 ORM 作为一个能简化 CURD 操作、免去繁琐的查询语句编写的存在,是被广大的 Web 开发者所熟知。但是,目前 NebulaGraph 社区有 Golang 版本的 ORM norm、Java ORM NGBatisgraph-ocean 唯独没有 Hao 所熟悉的 Python 语言的 ORM。

于是,做一个 NebulaGraph Python ORM 的想法便诞生了。

NebulaGraph Python ORM

Nebula Carina 名字的由来

NebulaGraph Python ORM,又名 nebula-carina,虽然目前只是一个雏形,但是已经基本上具备了一个 ORM 的基础功能。在命名 Python ORM 项目之时,Hao 先想到了 nebula-model,见名便知这是一个 ORM,搞了一些封装。但它不够优雅(cool),所以 nebula-carina 便诞生了。

Carina 船底座,/kəˈriːnə/,意为龙骨,是南半球可见最大的星云。而一个组件能成为一个 Nebula(星云)还挺酷的。

Python ORM 功能设计

Nebula Carina 是用 Python 开发的针对 NebulaGraph + Python 的 ORM 框架。在设计上没有局限于 Web 框架,因此可以被应用在 Django、FastAPI 和 Flask 等主流框架上。

目前,Nebula Carina 包含了常规的 schema 定义、对象管理器 object manager(雏形)、Model Builder(雏形),以及常见的图语言、MATCH 语句封装。雏形的意思是,这些功能具备了,但是暂时只有一、两个方法在里面,欢迎阅读本文的你一起来完善。除了基础功能之外,Nebula Carina 还支持了简单的 migration 功能,能够自动计算 schema model 结构与 DB schema 的差异,并同步 schema 到当前 space。但相较于其他成熟的 ORM 项目,例如:Django ORM,Nebula Carina 缺少可回溯性及树状结构来支持 migration 包含依赖、merge 数据。所以,Nebula Carina 未来考虑设计和支持包含依赖关系的 migration 系统。如果你对此有兴趣的话,欢迎来项目:https://github.com/nebula-contrib/nebula-carina issue 区交流下。

Python ORM 的神奇之处

上面简单说了下 Nebula Carina 是什么,有什么功能。在这里,我们来解决下“为什么要用 Nebula Carina”的问题。

Nebula Carina 首要应对的问题是快速解决轻量级 App 开发的常规需求,虽然 NebulaGraph 具有极好的性能,诸如美团、快手等大企业都在使用。但大企业和小公司不同,大企业用图数据库会用非常重,像美团就直接开发了个图平台对接集团上百的业务线。而小公司的轻量级应用来说,它需要一个快速地生成简洁 schema。小公司的 Web 开发人员能非常容易地定义常用的、供于业务逻辑使用的 schema,再一键快速将 schema 同步到 space,而不需要去写些 SQL(这里指的是查询语句)来处理这些事项。此外,应对小公司的轻量级 App 开发需求,还需要支持 JSON 序列化和逆序列化来简化接口,不需要在接口处封装各类东西。最后,也是最重要的,为什么不用 Golang 之类的语言 ORM。Nebula Carina 采用了易于使用的 Python Data Model。Python 使用人员可以方便地用 Python 来调用、控制程序,像是打印,或者是在 Python Model 里面将 Dictionary 展开时拥有的 fields 都可以符合标准 Python 规范进行使用。

此外,除了适用于任何的 Python Web Framework,Nebula Carina 也适用于裸 Python 开发,可与 AI 行业快速集成。毕竟像是 Machine Learning 之类的,十有八九是 Python 语言搞的,Nebula Carina 就可以轻松应用在 GNN、NLP 这些用图数据比较多的技术领域。

总之,Nebula Carina 让 Python 开发者使用 NebulaGraph 时能把更多精力运用在业务/模型上,而非繁琐的数据库操作。

Python ORM 设计实现

目前,Carina 的实现比较简单粗暴,由 4 个部分组成:settingsnGQL 层model 层其他

settings,搞环境变量。

nGQL 层,有 connection、query、record、schema 和 statement:

  • query,主要是 condition / match / … 语句封装
  • record,主要是 vertex / edge 语句封装
  • schema,封装了 Data Types、schema 语句、space 语句封装
  • statements,主要是 Order By、Limit、Edge 定义、Edge Value、TTL、Alter 等 statements 的语句封装,statement 的意思是 state 某类行为;

model 层,主要是调用 nGQL 层的封装的 class 和当中的方法,来解决一些具体上层的问题。它包括 nebula-python 的 vertex / edge 转成 Carina 的 vertex model / edge model 的 protocol,以及 field 和 model(schema model & data model)的封装,同绝大数编程语言的 ORM 类似,定义成某类语言常见的 class 进行封装,参见下方 Figure 类的示例说明;

class Figure(models.TagModel):
    name: str = _(data_types.FixedString(30), ..., )
    age: int = _(data_types.Int16, ..., )
    valid_until: int = _(data_types.Int64, None, )
    hp: int = _(data_types.Int16, 100, )
    style: str = _(data_types.FixedString(10), 'rap', )
    is_virtual: bool = _(data_types.Bool, True)
    created_on: datetime = _(data_types.Datetime, data_types.Datetime.auto)
    some_dt: datetime = _(data_types.Datetime, datetime(2022, 1, 1))

上述示例代码,用 Figure class 继承 TagModel,在当中定义 tag 所需的这些 field,比如:name、age…Carina 就是采用这种方式来处理 NebulaGraph 中 Schema 结构;

model 层中的 model builder 则是位于 nGQL 和纯 model 层之间的桥梁。它可以用来描述高层和低层之间的某种行为,比如说,下面的代码就定义了一个全局 MATCH 语句,而所有的 MATCH 语句都会走这样一个函数同 nGQL 层交互:

def match(
    pattern: str, to_model_dict: dict[str, Type[NebulaConvertableProtocol]],
    *, distinct_field: str = None,
    condition: Condition = None, order_by: OrderBy = None, limit: Limit = None
) -> Iterable[SingleMatchResult]:  # should be model
    output = ', '.join(
    ("DISTINCT " if key == distinct_field else "") + key
    for key in to_model_dict.keys()
)
results = match(pattern, output, condition, order_by, limit)
return (
    SingleMatchResult({
        key: to_model_dict[key].from_nebula_db_cls(value.value)
        for key, value in zip(results.keys(), row.values) if key in to_model_dict
    }) for row in results.rows()
) 

而 model 层的 object manager 会根据应用场景,基于 schema 为出发点,对 model builder 具体 match 语句进行操作,对这些操作行为搞了个高级封装;migrations 则负责封装 schema model 的变更并同步给数据库;

其他模块,则是 Django 适配的 apps 和 setting。因为要支持 Django,它的思路同 FastAPI 不同,所以需要做适配来让 Carina 无缝衔接 Django;

Nebula Carina 使用

下面举些例子来让大家了解下 Carina 的使用,主要还是摘录自 Carina 的 README:https://github.com/nebula-contrib/nebula-carina

安装 Nebula Carina

一句命令搞定

pip install nebula-carina

如果你用的是 Django,那么需要将 nebula_carina 添加到 INSTALLED_APPS,像是这样:

INSTALLED_APPS = [
    ...
    'nebula_carina',
    ...
]

再在 settings.py 文件中设置 CARINA_SETTINGS,主要配置一些同 NebulaGraph 有关的信息。像是这样:

CARINA_SETTINGS = {
    "auto_create_default_space_with_vid_desc": "FIXED_STRING(20)", #创建默认图空间
    "default_space": "main", #图空间名
    "max_connection_pool_size": 10, #连接数大小
    "model_paths": ["nebula.carina"], #model 路径
    "user_name": "root", #登陆 NebulaGraph 的用户名
    "password": "1234", #登陆 NebulaGraph 的密码
    "servers": ["192.168.31.248:9669"], # NebulaGraph graphd 服务所在服务器信息,可配置多个
    "timezone_name": "UTC", #服务器所用时区
}

目前 Carina 只有支持上述信息,后续会再增加其他字段。

如果你用的是 FastAPI 之类的,用环境变量即可,具体的话可以参考项目文档:https://github.com/nebula-contrib/nebula-carina#by-environment-variables

图空间创建

你可以通过下面 Python 语句来创建 Space,当然你也可以像上面 CARINA_SETTINGS 一样,用 "auto_create_default_space_with_vid_desc": "FIXED_STRING(20)" 自动创建一个默认图空间。

from nebula_carina.ngql.schema.space import create_space, show_spaces, VidTypeEnum

main_space_name = "main"

if main_space_name not in show_spaces():
    create_space(main_space_name, (VidTypeEnum.FIXED_STRING, 20))

点边 schema 定义

同点 vertex 不同,一条边只有一个 edgetype,而一个点可以拥有多个 tag。所以在 Carina 中,Model 层的封装,models.py 文件里引入了 VirtualCharacter 的概念,在 VirtualCharacter 类里,定义这个点拥有那些 tag。

class VirtualCharacter(models.VertexModel):
    figure: Figure
    source: Source

一个 figure 就是一个 tag,source 是另外一个 tag 的名字。这里 Figure 和 Source 都是具体的某个 tag 在 Carina 中的映射类名,在示例中,它就叫 Figure、Source。

点边数据操作

上文提过 VirtualCharacter 的概念,在 Data Model Mathod 里,像下面这种代码:

VirtualCharacter(
    vid='char_test1', figure=Figure(
        name='test1', age=100, is_virtual=False, some_dt=datetime(2021, 3, 3, 0, 0, 0, 12)
    ), source=Source(name='movie1')
).save()

是定义了一个 VID(唯一标识)为 char_test1 的点,它拥有个名为 Figure 的 tag,这个 tag 中有 name、age、is_virtual 之类的属性。此外,它还有一个 tag Source,Source tag 的属性 name 是 movie1。而 .save() 则是保存这段代码。

同点类似,边的定义是这样的:

EdgeModel(src_vid='char_test1', dst_vid='char_test2', ranking=0, edge_type=Love(way='gun', times=40)).save()

这个语句主要表达了一条边的起点是 char_test1,终点是 char_test2,边的 rank 是 0,类型是 Love。而 Love 边类型有 2 个属性 way 和 times,😂 也许这是一对相杀相爱的恋人,滚了 40 次。

Nebula Carina 再升级

因为个人能力有限,在这里希望借助大家的力量。对 Nebula Carina 的未来规划,主要集中在这些方面

  • connection pool (v3.3.0)
  • Indexes
  • Go / Fetch / Lookup statements封装
  • Bulk操作封装
  • Generic Vertex Model
  • advanced migrations

nebula-python 在 v3.3.0 中对 connection pool 做了原生支持,希望在未来 Carina 能结合这块内容更加完善。

再者就是索引,上面其实提到过,Carina 目前就封装了 MATCH 语句,后续将会对 LOOKUP、GO、FETCH 之类的 statement 字句进行封装。

然后是 Bulk 操作的封装,可以处理一次性创建大量数据。

Generic Vertex Model 则是再抽象 vertex,用户不需要告诉程序它想得到什么样的 vertex,它的结构是如何的。直接通过虚拟结构进行定义,像是上面提到的 Figuer 和 Source,现在我不定义了,Generic Vertex Model 可以把这块抽象好,自己就搞定了。

最后,之前也提到过的 advanced migrations,树状的 migration 可以搞定依赖关系。

以上,便是 Hao 贡献的 NebulaGraph Python ORM 的简单介绍。如果你有改进、优化它的 idea,欢迎来 Carina issue 和 pr 区交流哟 https://github.com/nebula-contrib/nebula-carina/issues/new~


谢谢你读完本文 (///▽///)

NebulaGraph Desktop,Windows 和 macOS 用户安装图数据库的绿色通道,10s 拉起搞定海量数据的图服务。通道传送门:http://c.nxw.so/c0svX

想看源码的小伙伴可以前往 GitHub 阅读、使用、(^з^)-☆ star 它 -> GitHub;和其他的 NebulaGraph 用户一起交流图数据库技术和应用技能,留下「你的名片」一起玩耍呢~

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
15天前
|
人工智能 小程序
【一步步开发AI运动小程序】十五、AI运动识别中,如何判断人体站位的远近?
【云智AI运动识别小程序插件】提供人体、运动及姿态检测的AI能力,无需后台支持,具有快速、体验好、易集成等特点。本文介绍如何利用插件判断人体与摄像头的远近,确保人体图像在帧内的比例适中,以优化识别效果。通过`whole`检测规则,分别实现人体过近和过远的判断,并给出相应示例代码。
|
12天前
|
存储 人工智能 自然语言处理
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
ChatMCP 是一款基于模型上下文协议(MCP)的 AI 聊天客户端,支持多语言和自动化安装。它能够与多种大型语言模型(LLM)如 OpenAI、Claude 和 OLLama 等进行交互,具备自动化安装 MCP 服务器、SSE 传输支持、自动选择服务器、聊天记录管理等功能。
85 15
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
|
1天前
|
人工智能 自然语言处理 Java
【100%好礼】诚邀体验SoFlu-JavaAl开发助手,重塑AI编码价值
在这个数字化时代,软件开发任务繁重,飞算科技推出SoFlu-JavaAl开发助手,诚邀您体验AI编码新境界。它不仅生成代码,还通过自然语言理解需求,精准生成完整工程源码,大幅缩短设计工期,提升效率。SoFlu-JavaAl支持一键构建Java Maven工程,轻松合并老项目,快速响应需求变更。参与体验还有机会获多重好礼!
|
9天前
|
人工智能 小程序 API
【一步步开发AI运动小程序】十七、如何识别用户上传视频中的人体、运动、动作、姿态?
【云智AI运动识别小程序插件】提供人体、运动、姿态检测的AI能力,支持本地原生识别,无需后台服务,具有速度快、体验好、易集成等优点。本文介绍如何使用该插件实现用户上传视频的运动识别,包括视频解码抽帧和人体识别的实现方法。
|
14天前
|
人工智能 小程序 UED
【一步步开发AI运动小程序】十六、AI运动识别中,如何判断人体站位?
【云智AI运动识别小程序插件】提供人体、运动及姿态检测的AI能力,本地引擎无需后台支持,具备快速、体验好、易集成等优势。本文介绍如何利用插件的`camera-view`功能,通过检测人体站位视角(前、后、左、右),确保运动时的最佳识别率和用户体验。代码示例展示了如何实现视角检查,确保用户正或背对摄像头,为后续运动检测打下基础。
|
2天前
|
人工智能 前端开发 Java
Spring AI Alibaba + 通义千问,开发AI应用如此简单!!!
本文介绍了如何使用Spring AI Alibaba开发一个简单的AI对话应用。通过引入`spring-ai-alibaba-starter`依赖和配置API密钥,结合Spring Boot项目,只需几行代码即可实现与AI模型的交互。具体步骤包括创建Spring Boot项目、编写Controller处理对话请求以及前端页面展示对话内容。此外,文章还介绍了如何通过添加对话记忆功能,使AI能够理解上下文并进行连贯对话。最后,总结了Spring AI为Java开发者带来的便利,简化了AI应用的开发流程。
76 0
|
28天前
|
人工智能 小程序 IDE
【一步步开发AI运动小程序】九、姿态辅助调试桌面工具的使用
随着AI技术的发展,各大厂商推出的AI运动APP如“乐动力”、“天天跳绳”等,使云上运动会、线上健身等概念大热。本文将指导你如何利用“云智AI运动识别小程序插件”,在微信小程序中实现类似功能,包括工具搭建、服务启动及数据回传等步骤,助力开发者高效开发AI运动小程序。
【一步步开发AI运动小程序】九、姿态辅助调试桌面工具的使用
|
20天前
|
人工智能 小程序 API
【一步步开发AI运动小程序】十三、自定义一个运动分析器,实现计时计数02
本文介绍如何利用“云智AI运动识别小程序插件”开发AI运动小程序,详细解析了俯卧撑动作的检测规则构建与执行流程,涵盖卧撑和撑卧两个姿态的识别规则,以及如何通过继承`sports.SportBase`类实现运动分析器,适用于小程序开发者。
|
20天前
|
人工智能 小程序 API
【一步步开发AI运动小程序】十二、自定义一个运动分析器,实现计时计数01
随着AI技术的发展,AI运动APP如雨后春笋般涌现,如“乐动力”、“天天跳绳”等,推动了云上运动会、线上健身等热潮。本文将指导你从零开始开发一个AI运动小程序,利用“云智AI运动识别小程序插件”,介绍运动识别原理、计量方式及运动分析器基类的使用,帮助你在小程序中实现运动计时和计数功能。下篇将继续探讨运动姿态检测规则的编写。
|
10天前
|
人工智能 小程序 数据处理
uni-app开发AI康复锻炼小程序,帮助肢体受伤患者康复!
近期,多家康复机构咨询AI运动识别插件是否适用于肢力运动受限患者的康复锻炼。本文介绍该插件在康复锻炼中的应用场景,包括康复运动指导、运动记录、恢复程度记录及过程监测。插件集成了人体检测、姿态识别等功能,支持微信小程序平台,使用便捷,安全可靠,帮助康复治疗更加高效精准。