Sqlite Storage

作者 val-town2d3ec654b6a7无许可证收录于 2026年10月8日更新于 2026年10月8日

Use when a val needs to store structured or relational data. Covers the std/sqlite API, parameterized queries, transactions, and the val-scoped vs organization-scoped database distinction.

AI 生成的概览

指导在 Val Town 的 val 中使用内置 SQLite 存储结构化或关系型数据。

功能
该技能说明如何在 Val Town 中使用 std/sqlite 模块存储结构化或关系型数据。内容涵盖建表与参数化查询、通过 sqlite.batch 实现原子性的多语句事务,以及 val 级数据库与组织级数据库的区别。它还说明通过 sqlite_execute 或 sqlite_batch 工具查询组织所有的 val 时如何指定组织,并列出参数化、幂等建表与迁移的规则。
适用场景
当某个 val 需要持久化的关系型或结构化数据(例如用户、数据表或查询)时使用。它也适用于在 val 级与组织级数据库之间做选择,或编写事务与架构迁移的场景。对于简单的键值数据,技能建议改用 std/blob。
运行要求
需要 Val Town 平台及其内置的 std/sqlite 模块(从 esm.town 导入);该技能不附带任何脚本,仅为说明文档,所引用的 API 文档为外部资源。

SQLite Storage

Val Town provides built-in SQLite via the std/sqlite module. Reach for it whenever a val needs relational or structured persistent data. For simple key/value data, prefer std/blob instead.

Basic usage

ts
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]" }]

Transactions

Use sqlite.batch for atomic multi-statement transactions — all succeed or all roll back:

ts
await sqlite.batch([  { sql: "INSERT INTO users (name, email) VALUES (?, ?)", args: ["Bob", "[email protected]"] },  { sql: "UPDATE users SET name = ? WHERE id = ?", args: ["Robert", 2] },]);

Per-val vs organization databases

The import path determines which database you get. Both expose the same @libsql/client API (execute, batch) and return rows as keyed objects (Record<string, unknown>[]):

  • std/sqlite/main.ts — val-scoped database, isolated to this val. The default for new vals, and what you almost always want.
  • std/sqlite/global.ts — organization-scoped database, shared across every val owned by the same account. (Your personal account counts as its own organization here, so this database is shared across all of your vals.)

Do not switch an existing val between these import paths — it changes which database the val reads and writes.

Querying org-owned vals via tools

When using the sqlite_execute or sqlite_batch tools to query a val owned by an organization (not your personal account), pass the org handle as the org parameter so the call hits the right database. Example: { sql: "SELECT * FROM users", org: "some-org" }. This only matters for the tool calls — code inside the val itself reads from its own database automatically.

Rules

  • Always use parameterized queries (the args field) for any value derived from user input. Never interpolate strings into SQL.
  • Use CREATE TABLE IF NOT EXISTS so schema setup is idempotent across val restarts.
  • Schema migrations: add new columns with ALTER TABLE ... ADD COLUMN. Wrap in try/catch if the migration may run against an already-updated table.

Reference

Full API docs: https://docs.val.town/reference/std/sqlite/usage/

来源与署名

来源:val-town/plugins位于plugin/skills/sqlite-storage提交2d3ec65

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架