SpacetimeDB CLI 完全指南:从项目初始化、模块发布到数据库管理与服务器运维
【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB
本篇指南以 SpacetimeDB 开源仓库中的官方 CLI 参考文档(codex-plugin/plugins/spacetimedb/skills/cli/SKILL.md)为骨架,结合 crates/cli/src 的源码实现,系统讲解spacetime命令行工具的完整使用方式。读完本篇,你将掌握:如何用一条命令初始化多语言项目、在开发模式与发布流程之间平滑切换、通过 SQL/Reducer 与数据库交互、管理多台服务器与身份认证,以及遇到常见错误时的排查路径。
一、认识 spacetime CLI:命令体系总览
spacetime是 SpacetimeDB 的官方命令行工具,用于覆盖一个 SpacetimeDB 应用从诞生到运维的全生命周期:初始化项目、构建模块、发布数据库、执行查询、调用函数、订阅变更、查看日志以及管理服务器连接。
从源码看,CLI 基于 clap 构建,全部子命令在 crates/cli/src/lib.rs 的get_subcommands()中注册,当前包含:
- 项目与开发:
init、build、dev、generate - 发布与部署:
publish、delete、list、rename、dns、lock、unlock - 数据库交互:
sql、call、subscribe、logs、describe - 服务器与认证:
server、start、login、logout、version - 扩展能力:
mcp
命令入口在 crates/cli/src/main.rs,启动时会先解析参数、定位配置文件(cli.toml),再分发到各个子命令的exec函数。后续小节将按“初始化与开发 → 发布与部署 → 数据交互 → 管理与运维 → 认证 → 故障排查”的顺序逐一展开。
二、项目初始化与开发循环
2.1 用 init 创建多语言项目
spacetime init用于初始化新项目,支持指定服务端语言或直接选用模板:
# 按服务端语言初始化(Rust / C# / TypeScript / C++) spacetime init my-project --lang rust|csharp|typescript|cpp # 按模板 ID 初始化 spacetime init my-project --template <template-id> # 从 GitHub 仓库(owner/repo 或 git URL)初始化 spacetime init my-project --template owner/repo结合 crates/cli/src/subcommands/init.rs 的源码,init还支持以下重要选项:
| 选项 | 说明 |
|---|---|
--project-path <PATH> | 指定项目创建目录(默认./<PROJECT_NAME>) |
--server-only | 仅初始化服务端模块,不生成客户端 |
--local | 使用本地部署而非 Maincloud |
--non-interactive | 非交互模式(此时必须显式提供--template或--lang) |
--native-aot | 为 C# 项目配置 NativeAOT-LLVM 编译(实验性) |
--dotnet-version <8\|10> | 指定 C# 项目目标 .NET 大版本,省略时自动检测 |
实现细节上值得注意:模板分为内置模板(通过嵌入式templates.json获取,见 init.rs)与 GitHub 仓库两类;交互模式下会引导选择语言组合与模板,并提示登录(本地部署可跳过)。若选择 TypeScript 服务端,还会询问 npm/pnpm/yarn/bun 包管理器并自动安装依赖(见 init.rs)。初始化完成后会生成项目级配置文件spacetime.json(服务端位于spacetimedb/子目录,见 init.rs)与本地数据库配置spacetime.local.json。
2.2 build:编译模块
spacetime build # release 构建 spacetime build --debug # 快速迭代,运行期较慢build会按语言分派到对应的构建任务(crates/cli/src/tasks 下的rust.rs、csharp.rs、javascript.rs、cpp.rs)。Rust 模块最终编译为 wasm 二进制,TypeScript 模块则编译为 JS 产物,供后续publish上传。
2.3 dev:自动重建、自动发布、自动生成绑定
spacetime dev是日常开发的核心命令,它监听文件变化并自动完成“重新构建 → 重新发布 → 重新生成客户端绑定”,大幅缩短反馈循环:
spacetime dev spacetime dev --client-lang typescript --module-bindings-path ./client/src/module_bindings源码层面的行为(见 crates/cli/src/subcommands/dev.rs)补充了以下参数:
--project-path <PATH>:项目根目录,默认.--module-bindings-path <PATH>:客户端绑定输出目录(相对项目目录),默认src/module_bindings--module-path <PATH>:服务端模块目录,默认<project-path>/spacetimedb--client-lang <LANG>:生成的绑定语言(typescript/csharp/rust/unrealcpp),省略时自动探测--server <NAME>:发布目标服务器,未指定时用默认服务器(再缺省则 maincloud)--run <COMMAND>:启动客户端开发服务器的命令(覆盖 spacetime.json 中的dev.run)--server-only:只运行服务端,不启动客户端--delete-data <always|on-conflict|never>:dev 模式默认on-conflict--skip-publish/--skip-generate:跳过发布或生成步骤--env <ENV>:配置分层环境名,dev 默认dev(对应加载spacetime.dev.json)
模板约定:服务端代码统一放在spacetimedb/目录中,这是模板项目的硬性要求(见 dev.rs)。
2.4 generate:为客户端生成类型绑定
generate根据模块的 schema 生成客户端绑定代码,支持的--lang包括 TypeScript、C#、Rust 与 Unreal C++(unrealcpp):
spacetime generate --lang typescript|csharp|rust --out-dir ./bindings --module-path ./server spacetime generate --lang unrealcpp --uproject-dir ./MyGame --module-path ./server --unreal-module-name MyGameUnreal 场景必须同时提供--uproject-dir与--unreal-module-name,两者缺一不可(相关校验与测试见 crates/cli/src/subcommands/generate.rs 及 generate.rs 的测试用例)。generate也可以从项目配置文件中的generate条目读取语言与输出目录。
三、发布与部署
3.1 publish:创建与更新数据库
publish会先构建模块,再把产物上传到目标服务器,创建新数据库或更新已有数据库:
# 发布到 Maincloud(默认) spacetime publish my-database --yes # 发布到本地服务器 spacetime publish my-database --server local --yes # 清空数据库后重新发布 spacetime publish my-database --delete-data=always --yes发布实现(crates/cli/src/subcommands/publish.rs)中值得注意的细节:
- 数据库名必须匹配
/^[a-z0-9]+(-[a-z0-9]+)*$/,即仅允许小写字母、数字与连字符。 - 未指定
--module-path时,默认查找spacetimedb/子目录,否则用当前目录(见 publish.rs)。 --bin-path/--js-path可跳过构建直接发布已编译的 wasm / JS 产物(与--module-path、--build-options互斥)。- 发布到非本地服务器前会弹出确认;可通过
--yes跳过。 - 存在 schema 变更时,客户端会先调用
pre_publish接口做破坏性变更检查,必要时提示“此操作会破坏现有客户端”(见 publish.rs)。 --parent/--organization可将新数据库挂到父数据库或组织下,继承其团队权限(仅创建时有效)。--delete-data支持always/on-conflict/never三档,on-conflict仅在破坏性 schema 变更时清库。
--yes是值得单独说明的参数:它不只是“全选”,还支持细粒度控制(见 publish.rs 的YesValue枚举):--yes=all(默认)、--yes=remote、--yes=migrate、--yes=break-clients、--yes=skip-login、--yes=delete-data,多个值可用逗号分隔或重复传参,且必须使用等号连接(--yes my-db会被当作数据库名)。
3.2 数据库生命周期管理
# 列出数据库 spacetime list # 删除数据库 spacetime delete my-database # 重命名数据库(注意:用数据库 identity 定位,而非名称) spacetime rename <database-identity> --to new-name四、与数据库交互:SQL、Reducer、订阅与日志
4.1 sql:执行查询与交互式 REPL
spacetime sql my-database "SELECT * FROM users" spacetime sql my-database --interactive # REPL 模式sql命令(crates/cli/src/subcommands/sql.rs)额外支持:
--format <text|json>:输出格式,默认text--confirmed:只接收已确认事务的更新--anonymous:以匿名身份执行--server <SERVER>:指定目标服务器
执行结果会以表格形式展示,并附带统计信息(如(N rows)以及 inserted/deleted/updated 计数,见 sql.rs)。
4.2 call:调用 Reducer 与 Procedure
# 每个参数作为独立的位置参数传入 spacetime call my-database my_reducer '"value"' '123'call会从服务端拉取模块定义(ModuleDef),自动区分被调用对象是 Reducer 还是 Procedure(见 crates/cli/src/subcommands/call.rs),并支持点号限定的子模块名(如lib.my_reducer)。参数须逐个作为位置参数传入,字符串参数记得加引号。
4.3 subscribe:订阅数据变更
spacetime subscribe my-database "SELECT * FROM users" --num-updates 10subscribe以 SQL 订阅表达式建立长连接,--num-updates控制收到多少条更新后退出,便于脚本化观察数据流。
4.4 logs:查看模块日志
spacetime logs my-database -f # 持续跟随输出 spacetime logs my-database -n 100 # 最多显示最近 100 行-f等价于 tail -f,适合调试运行中的模块;-n限制读取行数。
4.5 describe:导出 Schema
spacetime describe my-database --json spacetime describe my-database table users --json spacetime describe my-database reducer my_reducer --jsondescribe可整体导出数据库 schema,也可按table、reducer等维度细分,--json输出结构化结果,便于与脚本或 CI 集成。
五、服务器管理与本地运行
5.1 默认服务器
CLI 预置两台服务器(源码默认值见 crates/cli/src/config.rs):
| 名称 | URL | 说明 |
|---|---|---|
maincloud | https://maincloud.spacetimedb.com | 生产云服务(默认) |
local | http://127.0.0.1:3000 | 本地开发服务器 |
5.2 server:管理服务器连接配置
# 列出已配置的服务器 spacetime server list # 添加服务器(--default 设为默认;--no-fingerprint 跳过指纹校验) spacetime server add local --url http://localhost:3000 --default spacetime server add myserver --url https://my-spacetime.example.com # 设置默认服务器 spacetime server set-default local # 测试连通性 spacetime server ping local # 清空本地数据 spacetime server clearserver子命令(crates/cli/src/subcommands/server.rs)还包含remove(删除配置)、fingerprint(查看/更新服务器指纹)、edit(修改昵称/主机/协议)等能力。添加服务器时会自动抓取并保存服务器指纹(TLS 固定),服务器不可达时可用--no-fingerprint跳过。ping实际请求<url>/v1/ping端点来判断服务是否在线(见 server.rs);clear则删除本地数据目录中的全部数据库数据(需二次确认,可用--yes跳过)。
5.3 start:启动本地实例
spacetime startstart启动一个本地 SpacetimeDB 实例(监听127.0.0.1:3000),供--server local场景使用;它与spacetime server clear配合可实现“本地数据整体重置”。
六、认证:登录、登出与身份管理
# 打开浏览器完成登录 spacetime login # 使用 token 直接登录(绕过浏览器流程) spacetime login --token <token> # 查看登录状态 spacetime login show # 登出 spacetime logout认证实现(crates/cli/src/subcommands/login.rs)说明:
--token直接把令牌写入本地配置,适合 CI 环境;show --token可查看已保存的令牌。--no-browser不自动打开浏览器;--auth-host <HOST>可从其他认证主机获取令牌。- 许多命令(如
sql、call、publish)支持--anonymous以匿名身份执行公开操作,无需登录。
七、常用全局参数
以下参数适用于大多数命令(定义于 crates/cli/src/common_args.rs):
| Flag | 短参 | 说明 |
|---|---|---|
--server <SERVER> | -s | 目标服务器(昵称、主机名或完整 URL) |
--yes | -y | 非交互模式,跳过确认 |
--anonymous | 使用匿名身份执行操作 | |
--module-path <DIR> | -p | 模块项目路径 |
此外,CLI 还提供全局的--root-dir <PATH>(spacetime 所有数据文件的根目录)与--config-path <PATH>(指定cli.toml配置文件,见 crates/cli/src/main.rs)。值得一提的还有--delete-data(-c)与--dotnet-version(仅 8/10 受支持,见 common_args.rs)。
八、项目配置文件 spacetime.json
init生成的项目会附带spacetime.json,将常用参数固化到项目里,避免每次敲命令都带一堆参数。其结构由 crates/cli/src/spacetime_config.rs 定义,支持:
{ "database": "my-database", "server": "local", "module-path": "./server", "dev": { "run": "pnpm dev" }, "generate": [ { "language": "typescript", "out-dir": "./src/module_bindings" } ] }配置要点:
- 顶层字段通过
--env支持环境分层(如spacetime.dev.json、spacetime.local.json),dev命令默认加载dev层。 - 多数据库场景可用
children数组定义多个数据库目标,子目标未设置的字段自动从父级继承(见 spacetime_config.rs)。 dev.run指定客户端开发服务器命令;generate条目可声明多语言的绑定生成配置。- 相关命令支持
--no-config忽略配置文件。
九、常见问题排查
9.1 “Not logged in”(未登录)
spacetime login # 或对公开操作使用 --anonymous9.2 “Server not responding”(服务器无响应)
spacetime server ping <server> # 若目标为 local,先确保已运行 spacetime startping会直接探测服务器/v1/ping端点,快速定位是网络问题还是实例未启动。
9.3 “Schema conflict”(Schema 冲突)
# 清空数据后重新发布 spacetime publish my-db --delete-data=always --yes若破坏性变更来自 schema 演进,也可改用--yes=break-clients单独放行“破坏现有客户端”的确认,或使用--delete-data=on-conflict仅在冲突时清库。
9.4 “Build failed”(构建失败)
# 检查工具链版本 rustup show # Rust 模块需确保已安装 wasm 目标 rustup target add wasm32-unknown-unknownC# 模块请确认 .NET SDK 版本(支持 8/10)与 NativeAOT 平台限制(macOS 上不受支持,Linux 需 .NET 10,见 common_args.rs);TypeScript 模块需确保所选包管理器(npm/pnpm/yarn/bun)已安装。
十、模块与客户端语言支持概览
| 角色 | 支持语言 |
|---|---|
| 服务端模块 | Rust、C#、TypeScript、C++ |
| 客户端 SDK | TypeScript、C#、Rust、Unreal Engine |
generate目标 | TypeScript、C#、Rust、Unreal C++ |
以上语言矩阵与 SKILL.md 保持一致,并通过 init.rs 的ServerLanguage/ClientLanguage枚举在实现层得到印证。整套 CLI 的设计目标,是让“写模块 → 本地验证 → 发布云端”这一循环只靠一个工具就能高效完成。
【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考