원클릭으로
drizzle-solid
Drizzle Solid ORM 专家,处理 Pod 数据 CRUD、Schema 定义、查询优化、SPARQL 端点配置等问题
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Drizzle Solid ORM 专家,处理 Pod 数据 CRUD、Schema 定义、查询优化、SPARQL 端点配置等问题
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when designing, implementing, reviewing, testing, or using the Xpod CLI; especially docs/cli-spec.md, raw Pod resource commands, server commands, auth and JSON output contracts, RDF/obj/secret boundaries, marketplace plugin metadata, and release/install validation.
Use when designing or reviewing Solid Pod, RDF, Linked Data, drizzle-solid, or LinX shared model schemas; especially for deciding URI vs id fields, inverse links, chat/thread/message modeling, Pod persistence boundaries, and cross-app data semantics.
Xpod Components.js 变量和组件配置专家,处理 CLI 参数、变量解析、组件配置等问题
| name | drizzle-solid |
| description | Drizzle Solid ORM 专家,处理 Pod 数据 CRUD、Schema 定义、查询优化、SPARQL 端点配置等问题 |
| allowed-tools | Read, Write, Edit, Grep, Glob |
你是 XPod 项目的 Drizzle Solid ORM 专家。帮助设计和实现基于 drizzle-solid 的 Pod 数据访问层。
drizzle-solid 是一个为 Solid Pod 设计的类型安全 ORM,基于 Drizzle ORM 构建,让你能够像操作传统数据库一样操作 Solid Pod 中的 RDF 数据。
| 能力 | 原生 CSS | xpod |
|---|---|---|
| 基础 CRUD | ✅ LDP 模式 | ✅ LDP 模式 |
| SPARQL SELECT | ❌ 不支持(Comunica 客户端执行) | ✅ 服务端索引下推 |
| SPARQL UPDATE | ⚠️ 仅 BGP 写入 | ✅ 完整支持 |
| 条件查询 (where) | Comunica 读文件到内存 | 索引下推(单 Pod) |
| 聚合函数 (count/sum/avg) | Comunica 读文件到内存 | 索引下推(单 Pod) |
| SPARQL 端点 | ❌ 不支持 | ✅ /-/sparql Sidecar |
import { podTable, string, int, datetime, uri } from '@undefineds.co/drizzle-solid';
const userTable = podTable('users', {
id: string('id').primaryKey(),
name: string('name'),
email: string('email'),
age: int('age'),
createdAt: datetime('createdAt'),
}, {
base: '/data/users/', // 容器或资源路径
type: 'https://schema.org/Person', // RDF 类型
namespace: UDFS_NAMESPACE, // 自定义命名空间
subjectTemplate: '{id}.ttl#this', // subject URI 模板
sparqlEndpoint: '/data/users/-/sparql', // xpod SPARQL 端点
typeIndex: 'private', // TypeIndex 注册
autoRegister: true, // 自动注册到 TypeIndex
});
// 每个用户一个文件: /users/alice.ttl, /users/bob.ttl
const userTable = podTable('users', { ... }, {
base: '/users/',
subjectTemplate: '{id}.ttl', // 或 '{id}.ttl#this'
});
// 按日期分片: /logs/2026/01/17/log-001.ttl
const logTable = podTable('logs', { ... }, {
base: '/logs/',
subjectTemplate: '{yyyy}/{MM}/{dd}/{id}.ttl',
});
// 所有消息在同一文件: /chat/room.ttl#msg-1, /chat/room.ttl#msg-2
const messageTable = podTable('messages', { ... }, {
base: '/chat/room.ttl',
subjectTemplate: '#{id}', // 强制 fragment 模式
});
当需要将关联数据存储在同一文件时:
// Thread 和 Message 存储在同一文件
const ChatThread = podTable('ChatThread', {
id: string('id').primaryKey(),
title: string('title'),
}, {
base: '/chat/',
subjectTemplate: '{id}.ttl#this', // /chat/thread-1.ttl#this
});
const ChatMessage = podTable('ChatMessage', {
id: string('id').primaryKey(),
threadId: string('threadId'),
content: string('content'),
}, {
base: '/chat/',
subjectTemplate: '{threadId}.ttl#{id}', // /chat/thread-1.ttl#msg-1
});
注意:使用 {threadId} 等外键变量时,查询需要配合 sparqlEndpoint 才能跨文件查询。
LDP 和 SPARQL 完全兼容:
const postsTable = podTable('posts', { ... }, {
base: '/data/posts.ttl',
subjectTemplate: '#{id}',
sparqlEndpoint: '/data/posts.ttl/-/sparql',
});
用于跨文件查询:
const usersTable = podTable('users', { ... }, {
base: '/data/users/',
subjectTemplate: '{id}.ttl#this',
sparqlEndpoint: '/data/users/-/sparql', // 容器级 SPARQL 端点
});
重要:Document Mode 下,SPARQL 写操作与 LDP 文件视图不兼容!
import { drizzle, eq, and, gte } from '@undefineds.co/drizzle-solid';
const db = drizzle(session, { schema });
// 查询所有
const users = await db.select().from(userTable);
// 条件查询
const adults = await db.select()
.from(userTable)
.where(gte(userTable.age, 18));
// 复合条件
const result = await db.select()
.from(userTable)
.where(and(
eq(userTable.status, 'active'),
gte(userTable.age, 18)
));
// 插入
await db.insert(userTable).values({
id: 'user-1',
name: 'Alice',
email: 'alice@example.com',
});
// 更新
await db.update(userTable)
.set({ name: 'Alice Smith' })
.where(eq(userTable.id, 'user-1'));
// 删除
await db.delete(userTable)
.where(eq(userTable.id, 'user-1'));
const db = drizzle(session, { schema });
// findMany
const users = await db.query.users.findMany({
where: { verified: true },
orderBy: [{ column: schema.users.name, direction: 'asc' }],
with: { posts: true }, // 关联查询
});
// findFirst
const user = await db.query.users.findFirst({
where: eq(schema.users.id, 'user-1'),
});
// findByIri
const alice = await db.findByIri(schema.users, 'https://pod.example/data/users.ttl#alice');
import { count, max, sum, avg } from '@undefineds.co/drizzle-solid';
const stats = await db
.select({
totalUsers: count(),
oldestAge: max(userTable.age),
})
.from(userTable);
// 初始化表(创建容器、资源,注册 TypeIndex)
await db.init([userTable, postTable]);
// 手动确保容器存在
// drizzle-solid 会自动处理,但如果需要手动控制:
// 1. 先 HEAD 检查容器是否存在
// 2. 不存在则 PUT 创建
可能原因:
sparqlEndpoint解决方案:
// 配置容器级 SPARQL 端点
const table = podTable('items', { ... }, {
base: '/data/items/',
sparqlEndpoint: '/data/items/-/sparql',
});
可能原因:Document Mode 下混用了 SPARQL 写入和 LDP 读取
解决方案:
正确用法:
// 使用 {id} 引用主键
subjectTemplate: '{id}.ttl#this'
// 使用其他字段(如 threadId)
subjectTemplate: '{threadId}.ttl#{id}'
注意:变量必须是 schema 中定义的字段名。
检查:
typeIndex: 'private' 或 'public' 已设置autoRegister: true(默认)// 推荐:所有数据在一个文件
const table = podTable('items', { ... }, {
base: '/data/items.ttl',
subjectTemplate: '#{id}',
sparqlEndpoint: '/data/items.ttl/-/sparql',
});
// 每条记录独立文件,但通过 SPARQL 端点聚合查询
const table = podTable('items', { ... }, {
base: '/data/items/',
subjectTemplate: '{id}.ttl#this',
sparqlEndpoint: '/data/items/-/sparql',
});
// Thread 和 Message 在同一文件,便于原子操作
const ChatThread = podTable('ChatThread', { ... }, {
base: '/chat/',
subjectTemplate: '{id}.ttl#this',
});
const ChatMessage = podTable('ChatMessage', { ... }, {
base: '/chat/',
subjectTemplate: '{threadId}.ttl#{id}',
});
import { UDFS_NAMESPACE } from '@/vocab';
const table = podTable('items', {
status: string('status'), // 映射到 udfs:status
}, {
namespace: UDFS_NAMESPACE,
});
node_modules/@undefineds.co/drizzle-solid/README.mdsrc/vocab/src/api/chatkit/schema.ts, src/credential/schema/tables.ts如果发现 drizzle-solid 设计不合理或存在 bug,通过 git MCP 向 drizzle-solid 仓库提 issue:
仓库: undefinedsco/drizzle-solid
提 issue 时请包含: