如何在 PostgreSQL 上安装 Apache AGE 并把 Semantica 图存储首次跑通?
【免费下载链接】semanticaGraph-Native Infrastructure for Context and Accountable AI Systems项目地址: https://gitcode.com/GitHub_Trending/sema/semantica
Semantica 的graph_store模块提供统一的图数据库接口,其中backend="age"可以把图数据直接存进 PostgreSQL + Apache AGE,不需要单独的图数据库服务——适合团队已经在运行 PostgreSQL、又想用 openCypher 查询图数据的场景。本文的目标是:装好依赖、连上一个已安装 AGE 扩展的 PostgreSQL 实例,跑通第一次节点写入和查询,并用文档给出的方式验证结果。
前提版本要求来自项目文档:
| 组件 | 要求 |
|---|---|
| PostgreSQL | 12+ |
| Apache AGE | 1.4+(需自行编译安装到 PostgreSQL 实例中) |
| psycopg2 | 2.9+ |
| Python | 3.8+(推荐 3.11+) |
需要特别注意一点:Apache AGE 必须编译并安装进你的 PostgreSQL 实例,这部分在 PostgreSQL/AGE 一侧完成,Semantica 文档不会替你安装它。Semantica 侧只负责通过psycopg2驱动连接并初始化扩展。
准备条件:安装 Semantica 和驱动
第一步是安装 Semantica 本体。根据 安装文档:
pip install semantica验证安装是否成功(文档给出的验证命令):
python -c "import semantica; print(semantica.__version__)"AGE 后端的 Python 驱动是psycopg2,需要额外安装:
pip install psycopg2-binary如果缺少psycopg2,ApacheAgeStore构造时会记录警告,connect()时会直接抛出ProcessingError,提示安装psycopg2-binary。
关于 AGE 扩展本身,文档给出两种准备方式:
- 已有 PostgreSQL 12+:自行按 Apache AGE 的官方安装流程把扩展编译安装进去(文档指向 AGE 官方的 setup 指南,此处不再赘述,因为 Semantica 仓库不包含该流程)。
- 可选分支:用 Docker 起步。AGE 图存储文档 提供了一个 compose 片段,用
apache/age:latest镜像起一个自带 AGE 的 PostgreSQL,端口映射为5432:5432,环境变量POSTGRES_USER=postgres、POSTGRES_PASSWORD=secret、POSTGRES_DB=agedb:
services: age: image: apache/age:latest ports: - "5432:5432" environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: secret POSTGRES_DB: agedbdocker compose up -d注意docker compose up -d会启动一个后台容器并占用本机 5432 端口;如果该端口已被占用,需要先解决端口冲突或修改映射。
连接 Semantica 图存储:两条路径
连接参数只有两个核心项:connection_string(PostgreSQL 连接串)和graph_name(AGE 图名)。文档给出了两种入口。
主路径:统一门面GraphStore。接口与 Neo4j、FalkorDB 后端一致,backend 可写"age"或"apache_age":
from semantica.graph_store import GraphStore store = GraphStore( backend="age", connection_string="host=localhost dbname=agedb user=postgres password=secret", graph_name="semantica", ) store.connect()可选分支:直接使用ApacheAgeStore。需要 AGE 专属行为时(例如直接调用底层的execute_query并指定cols):
from semantica.graph_store.age_store import ApacheAgeStore store = ApacheAgeStore( connection_string="host=localhost dbname=agedb user=postgres password=secret", graph_name="my_graph", ) store.connect()两点必须做到:
- 构造时不会自动连接。文档明确警告:
GraphStore不会在构造时连接,任何操作前必须先调用store.connect(),或者使用上下文管理器写法with GraphStore(...) as store:自动关闭连接。 connection_string中的 host、dbname、user、password 要替换为你环境中的实际值,上面用的是文档示例中的 Docker 配置。
配置也可以通过环境变量或编程方式提供,等效于直接传参:
| 环境变量 | 说明 | 默认值 |
|---|---|---|
GRAPH_STORE_AGE_CONNECTION_STRING | PostgreSQL 连接串 | host=localhost dbname=agedb user=postgres password=postgres |
GRAPH_STORE_AGE_GRAPH_NAME | AGE 图名 | semantica |
from semantica.graph_store.config import graph_store_config graph_store_config.set("age_connection_string", "host=db.example.com dbname=prod_age user=app") graph_store_config.set("age_graph_name", "production")connect() 在做什么
connect()执行的是幂等初始化,可以重复调用,内部依次完成(见 AGE 文档 与 age_store.py 中的connect实现):
CREATE EXTENSION IF NOT EXISTS age;—— 加载 AGE 扩展;LOAD 'age';—— 在当前会话激活 AGE;SET search_path = ag_catalog, "$user", public;—— 设置搜索路径;- 若目标图不存在则创建。
任何一步失败都会回滚并抛出ProcessingError(形如Failed to connect to AGE: ...),其中带出的原始错误信息就是下一步排查的线索。
首次跑通:写入节点和关系并验证
下面这段按文档 Quick Start 示例组织,用统一门面写入两个Person节点和一条KNOWS关系,再查询回来:
from semantica.graph_store import GraphStore store = GraphStore( backend="age", connection_string="host=localhost port=5432 dbname=agedb user=postgres password=secret", graph_name="semantica", ) store.connect() alice = store.create_node(labels=["Person"], properties={"name": "Alice", "age": 30}) bob = store.create_node(labels=["Person"], properties={"name": "Bob", "age": 25}) store.create_relationship(alice["id"], bob["id"], "KNOWS", {"since": 2023}) result = store.execute_query("MATCH (p:Person) RETURN p", cols="p agtype") print(result["records"]) store.close()运行后result["records"]应包含刚写入的两个节点;文档中直连示例展示过create_node的返回形态(文档示例,ID 数值会随你的环境不同):
{"id": 844424930131969, "labels": ["Entity"], "properties": {"semantica_id": "ent-001", "value": "test"}}另外可以用store.get_stats()查看图统计,返回包含node_count、relationship_count、label_counts等字段的字典,用来确认节点和关系确实落库。
AGE 不支持cypher()调用内的$param参数绑定,Semantica 的 AGE 后端会把参数安全地转成 Cypher 字面量并自动转义,所以下面这种写法可以直接用:
result = store.execute_query( "MATCH (p:Person) WHERE p.age > $min_age RETURN p", parameters={"min_age": 25}, cols="p agtype", )自定义查询时,cols用来指定 SQL 包装的AS子句(例如cols="a agtype, r agtype, b agtype");省略时后端会尝试从RETURN子句推断列。
首次跑不通时检查哪些项
按文档给出的现象对应排查:
- 报
ProgrammingError(连接或执行 Cypher 时):文档明确说明,这表示你的 PostgreSQL 实例里没装 AGE 扩展。backend="age"依赖 AGE 扩展函数,必须先完成扩展的编译安装。 ProcessingError: psycopg2 is not available...:驱动缺失,执行pip install psycopg2-binary后重试。- 构造后直接调用写操作报错:确认已经先调用了
store.connect()(或使用with写法);connect()未调用前不会建立连接。 - 连接串问题:核对
connection_string的 host、port、dbname、user、password 是否与实际 PostgreSQL 实例一致;用环境变量配置时对应GRAPH_STORE_AGE_CONNECTION_STRING,默认值为host=localhost dbname=agedb user=postgres password=postgres。
两个必须知道的限制
跑通之后,文档强调了两个 AGE 特有约束,会直接影响后续数据设计:
- AGE 内部 ID 与应用语义 ID 是两套东西。AGE 自动生成的顶点/边 ID(大整数)暴露在每个返回 dict 的
"id"字段里,用于delete_node()、get_node()等图操作;你自己的业务标识应存进semantica_id属性。文档明确警告:不要把两者混用——图操作(删除、更新、遍历)用node["id"],应用层查找用node["properties"]["semantica_id"]。 - AGE 每个顶点只支持一个标签。Semantica 对此做了透明处理:
labels[0]作为主标签,labels[1:]存入顶点的labels属性数组;读取节点时会重建完整标签列表。因此传labels=["Person", "Employee"]不会报错,但在 AGE 侧只有一个Person标签。
参考与下一步
- Apache AGE 图存储文档:完整 API 表(
create_node、create_relationship、get_neighbors、shortest_path、create_index等)、事务行为说明(成功COMMIT、异常ROLLBACK并以ProcessingError重抛)。 - Graph Store 模块参考:统一 API 的方法清单、
QueryEngine参数化查询与缓存、批量加载create_nodes()的用法。 - 存储后端总览:说明 Apache AGE 适配器的状态为 built-in,并提示 Cypher 兼容性和属性处理可能与独立 LPG 引擎存在差异。
如果你的数据是在 Semantica 内部构建的知识图,GraphBuilder(merge_entities=True, graph_store=store)可以配合已连接的 AGE store 直接把图持久化进去(见 Quickstart 中“Persistent graph store”一节),这是把 AGE 存储接入完整流水线的下一步。
【免费下载链接】semanticaGraph-Native Infrastructure for Context and Accountable AI Systems项目地址: https://gitcode.com/GitHub_Trending/sema/semantica
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考