关于 sqlite-storage
用于在 Val 中使用内置 SQLite 的技能,适合需要关系型或结构化持久数据的场景。内容说明数据库作用范围、原子批处理、安全查询和模式设置。
主要功能
- 01使用 Val 级或组织级数据库
- 02执行原子多语句批处理
- 03对用户输入使用参数化查询
- 04创建表并应用模式迁移
适用场景
- 01为 Val 存储关系型数据
- 02在组织内多个 Val 之间共享数据库数据
- 03以原子方式更新多条记录
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ val-town/ plugins --skill sqlite-storage安装后在 Claude Code 中输入/sqlite-storage确认已加载。
详细介绍
SQLite 存储
Val Town 通过 std/sqlite 模块提供内置 SQLite。只要 val 需要关系型或结构化的持久化数据,就使用它。对于简单的键值数据,优先使用 std/blob。
基本用法
import { sqlite } from "https://esm.town/v/std/sqlite/main.ts";
await sqlite.execute(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)`);
await sqlite.execute({
sql: "INSERT INTO users (name, email) VALUES (?, ?)",
args: ["Alice", "[email protected]"],
});
const result = await sqlite.execute("SELECT * FROM users");
// result.rows = [{ id: 1, name: "Alice", email: "[email protected]" }]
事务
使用 sqlite.batch 执行原子性的多语句事务——要么全部成功,要么全部回滚:
await sqlite.batch([
{ sql: "INSERT INTO users (name, email) VALUES (?, ?)", args: ["Bob", "[email protected]"] },
{ sql: "UPDATE users SET name = ? WHERE id = ?", args: ["Robert", 2] },
]);
按 val 或组织划分的数据库
导入路径决定你使用哪个数据库。两者都提供相同的 @libsql/client API(execute、batch),并将行作为键控对象(Record<string, unknown>[])返回:
std/sqlite/main.ts— 按 val 作用域划分的数据库,仅供此 val 使用。新 val 的默认选项,也是几乎所有情况下的首选。std/sqlite/global.ts— 按组织作用域划分的数据库,由同一账户拥有的所有 val 共享。(你的个人账户在这里也视为一个独立组织,因此此数据库由你的所有 val 共享。)
不要在现有 val 中切换这两种导入路径——这会改变该 val 读写的数据库。
使用工具查询组织拥有的 val
使用 sqlite_execute 或 sqlite_batch 工具查询组织拥有的 val(而非个人账户拥有的 val)时,请将组织句柄作为 org 参数传入,这样调用才能访问正确的数据库。例如:{ sql: "SELECT * FROM users", org: "some-org" }。这仅适用于工具调用——val 内部的代码会自动读取其自身的数据库。
规则
- 对任何源自用户输入的值,始终使用参数化查询(
args字段)。切勿将字符串插入 SQL。 - 使用
CREATE TABLE IF NOT EXISTS,确保在 val 重启时重复设置架构也不会产生问题。 - 架构迁移:使用
ALTER TABLE ... ADD COLUMN添加新列。如果迁移可能在已更新的表上运行,请用try/catch包裹。
参考
评论
支持 Markdown