appwrite-cli
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAppwrite CLI
Appwrite CLI
appwrite <command> --helpappwrite <command> --helpConfig vs client
client配置文件 vs client
命令
clientA real project (repo, schema, functions, deploys, CI) lives in . Init once. Pull and push after that. Do not on every command — the config already names the project.
appwrite.config.jsonappwrite client --project-idA one-off (inspect a user, patch one row, poke a remote you will not return to) uses . Do not scaffold a project for a single API call.
appwrite clientbash
undefined正式项目(代码库、架构、函数、部署、CI流程)的配置存储在中。只需初始化一次,之后使用pull和push命令同步。不要在每个命令中都使用——配置文件中已经指定了项目ID。
appwrite.config.jsonappwrite client --project-id一次性操作(查看用户信息、修改单行数据、访问不会再使用的远程资源)使用命令。不要为单次API调用搭建完整项目结构。
appwrite clientbash
undefinedGood — project
推荐操作 — 正式项目流程
appwrite login
appwrite list-projects --json
appwrite init project --project-id <ID>
appwrite pull table
appwrite login
appwrite list-projects --json
appwrite init project --project-id <ID>
appwrite pull table
edit appwrite.config.json, then:
编辑appwrite.config.json后执行:
appwrite push table --force
appwrite push table --force
Bad — project treated as a pile of API calls
不推荐操作 — 将项目当作零散API调用处理
appwrite tablesdb create-table --database-id main --table-id songs ...
appwrite tablesdb create-varchar-column --database-id main --table-id songs ...
appwrite tablesdb create-table --database-id main --table-id songs ...
appwrite tablesdb create-varchar-column --database-id main --table-id songs ...
the next clone has no record of this
下次克隆项目时,这些操作记录会丢失
Good — one-off (already logged in)
推荐操作 — 一次性操作(已登录状态)
appwrite client --project-id <ID>
appwrite users get --user-id <ID> --json
appwrite client --project-id <ID>
appwrite users get --user-id <ID> --json
Bad — one-off that litters a repo
不推荐操作 — 在无关仓库中生成项目文件
cd ~/some-unrelated-app && appwrite init project
No session? `appwrite client --endpoint https://<REGION>.cloud.appwrite.io/v1 --key "$APPWRITE_API_KEY" --project-id <ID>`.
`appwrite client --project-id` writes `appwrite.config.json` in this directory (or updates one found walking up). That is how you link a folder quickly. Do not run it at the root of an unrelated repo. `APPWRITE_PROJECT_ID` / `APPWRITE_ENDPOINT` override the file without touching it — use those when you are already inside a project and need a one-shot against something else.cd ~/some-unrelated-app && appwrite init project
无会话时?使用`appwrite client --endpoint https://<REGION>.cloud.appwrite.io/v1 --key "$APPWRITE_API_KEY" --project-id <ID>`。
`appwrite client --project-id`会在当前目录(或向上遍历找到的目录)中写入/更新`appwrite.config.json`,这是快速关联文件夹的方式。不要在无关仓库的根目录运行该命令。环境变量`APPWRITE_PROJECT_ID`/`APPWRITE_ENDPOINT`会覆盖配置文件内容但不会修改文件——当你已在项目目录中,需要对其他资源执行一次性操作时可以使用这些变量。Auth is not the project
身份认证与项目是分离的
| Layer | Lives in | Set with |
|---|---|---|
| Who you are (session or API key) | global CLI prefs | |
| Which project | | |
init projectbash
undefined| 层级 | 存储位置 | 设置方式 |
|---|---|---|
| 身份信息(会话或API密钥) | 全局CLI偏好设置 | |
| 项目归属 | | |
init projectbash
undefinedGood — CI against a checked-in config
推荐操作 — CI流程使用已提交的配置文件
appwrite client --key "$APPWRITE_API_KEY"
appwrite push function --force
appwrite client --key "$APPWRITE_API_KEY"
appwrite push function --force
Bad — CI that bakes the key into the repo
不推荐操作 — CI流程将密钥硬编码到仓库
appwrite client --key 'standard_....'
appwrite client --key 'standard_....'
and commits appwrite.config.json with secrets inside
并提交包含密钥的appwrite.config.json
Env beats the config: `APPWRITE_PROJECT_ID`, `APPWRITE_ENDPOINT`, `APPWRITE_ORGANIZATION_ID`. Check in the config (no secrets). Put keys in the environment.
`--force` skips prompts. Agents and CI have no TTY, so a push that needs confirmation fails without it (`Pass --force instead`). Ask the user, then pass `--force`. Do not use it to skip a change table whose local column is empty.
`appwrite login --switch` rotates saved accounts. `appwrite client --debug` prints the effective endpoint/project with credentials masked. `appwrite client --reset` signs out of everything.
环境变量优先级高于配置文件:`APPWRITE_PROJECT_ID`、`APPWRITE_ENDPOINT`、`APPWRITE_ORGANIZATION_ID`。提交配置文件时不要包含敏感信息,密钥应存储在环境变量中。
`--force`参数会跳过确认提示。代理和CI环境没有交互终端,因此需要确认的push操作如果不加该参数会失败(提示`Pass --force instead`)。在需要确认用户操作后再使用该参数,不要用它跳过本地列为空的表格变更。
`appwrite login --switch`可切换已保存的账户。`appwrite client --debug`会打印生效的端点/项目信息,并隐藏凭证。`appwrite client --reset`会登出所有账户。Cloud endpoints
Cloud区域端点
appwrite whoamihttps://cloud.appwrite.io/v1https://fra.cloud.appwrite.io/v1init projectclient --project-idbash
undefinedappwrite whoamihttps://cloud.appwrite.io/v1https://fra.cloud.appwrite.io/v1init projectclient --project-idbash
undefinedGood — project work uses the config's regional endpoint
推荐操作 — 项目操作使用配置文件中的区域端点
cat appwrite.config.json # "endpoint": "https://fra.cloud.appwrite.io/v1"
cat appwrite.config.json # "endpoint": "https://fra.cloud.appwrite.io/v1"
Bad — "fixing" whoami
不推荐操作 — 错误修改whoami的端点
appwrite client --endpoint https://fra.cloud.appwrite.io/v1
appwrite client --endpoint https://fra.cloud.appwrite.io/v1
now login/session calls go to a region host they do not belong on
现在登录/会话请求会发送到区域主机,这不符合设计逻辑
undefinedundefinedSchema vs rows
架构与数据行
| Pull / push (config) | Service commands (not in the config) |
|---|---|
| settings, functions, sites, tables and columns, buckets, teams, webhooks, topics | rows, users, files, executions, messages |
If it should survive a fresh clone, it belongs in the config. Edit the file, then push. Creating the same resources with or bypasses the file the next / expects.
tablesdb create-*functions createpullpushdatabasestablesdbpush tableIf the change table shows remote values against empty local, the config is missing those fields. Pull that resource, then push. Do not through it, and do not pull everything as a ritual — is slow.
--forcepull settingstext
id │ key │ remote │ local
───────────────┼─────────────────┼────────┼───────
Service │ account │ true │
Auth method │ email-password │ true │bash
undefined| Pull / push(配置文件同步) | 服务命令(不写入配置文件) |
|---|---|
| 设置、函数、站点、表与列、存储桶、团队、Webhook、主题 | 数据行、用户、文件、执行记录、消息 |
如果资源需要在全新克隆项目后保留,就应该存入配置文件。编辑配置文件后执行push。使用或创建的资源不会被后续的pull/push命令识别。
tablesdb create-*functions createdatabasestablesdbpush table如果变更表显示远程有值但本地为空,说明配置文件缺少这些字段。先pull该资源,再执行push。不要用强制跳过,也不要习惯性pull所有资源——速度较慢。
--forcepull settingstext
id │ key │ remote │ local
───────────────┼─────────────────┼────────┼───────
Service │ account │ true │
Auth method │ email-password │ true │bash
undefinedGood — local column was empty, so sync first, then push
推荐操作 — 本地列为空时先同步,再push
appwrite pull settings
appwrite push settings --force
appwrite pull settings
appwrite push settings --force
Bad — empty local, forced through
不推荐操作 — 本地为空时强制push
appwrite push settings --force
`push all --all --force` pushes every resource. Scope it (`push function --function-id api`) unless you mean that.
`unique()` is fine for a one-shot row or user. Resources you will push need a **stable** `$id` in the config so the next pull matches.appwrite push settings --force
`push all --all --force`会推送所有资源。除非确实需要,否则请限定范围(如`push function --function-id api`)。
`unique()`适合一次性数据行或用户创建。需要push的资源在配置文件中需要**稳定**的`$id`,这样后续pull才能匹配。Type-safe application code
类型安全的应用代码
When writing application code against TablesDB, inspect before inventing interfaces, database IDs, table IDs, or column names. The generators read the local config; they do not inspect the remote schema. A stale config produces stale code.
appwrite.config.jsonIf the remote schema is the source of truth, update the config first with . Do not pull over local, unpushed schema edits. If the local config is ahead, generate from it as-is.
appwrite pull tableFor TypeScript, prefer . It emits a complete TablesDB wrapper: database and table choices, create/update payloads, returned rows, query fields, and query values are checked by TypeScript. This is stronger than generated model interfaces alone.
appwrite generatebash
appwrite generateUse the generated API instead of dropping back to raw string IDs and handwritten payload types:
typescript
import { databases, type Songs } from "./generated/appwrite/index.js";
// Database lookup uses its ID; table lookup uses its name from the config.
const songs = databases.use("main").use("Songs");
const page = await songs.list({
queries: (query) => [
query.equal("published", true),
query.orderDesc("createdAt"),
query.limit(20),
],
});
const first: Songs | undefined = page.rows[0];Do not guess the literals in that example: read the generated types or the config. In particular, for a table takes its , which may differ from its . Let compilation expose a misspelled table, column, or wrong query value. Run the project's type checker after generation.
.use()name$idgenerateAPPWRITE_API_KEYappwrite generate --helpFor another supported language, or when the project deliberately uses the regular SDK directly, use . It supports TypeScript (), JavaScript (), PHP (), Kotlin (), Swift (), Java (), Dart (), and C# (). Pass these short values to ; names such as and are not the command's accepted values. Generated files type row data, but they do not type-check raw database/table IDs or calls:
appwrite types <output-directory>tsjsphpkotlinswiftjavadartcs--languagetypescriptcsharpQueryFor TypeScript, pass a destination when the result will be imported as a module. Passing a directory instead creates inside it.
.tsappwrite.d.tsbash
appwrite types ./src/appwrite-types.ts --language tstypescript
import { Client, TablesDB } from "appwrite";
import type { Songs } from "./appwrite-types.js";
// Read these values from appwrite.config.json and expose them through the
// application's existing configuration mechanism.
const client = new Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>");
const tablesDB = new TablesDB(client);
const page = await tablesDB.listRows<Songs>({
databaseId: "main", // still an unchecked string
tableId: "songs", // still an unchecked string
});Do not describe as “full type safety.” It only converts field names to the target language's naming conventions. Use when a fully typed TypeScript table API is the goal.
types --strictgenerateGenerated code is derived output. Do not patch it to fix a schema or naming problem; fix or the generator inputs and regenerate. After every table or column change, rerun the same generation command the repository uses and run its formatter/type checker. Preserve the repository's existing output path and check-in convention.
appwrite.config.json当针对TablesDB编写应用代码时,先查看,不要自行定义接口、数据库ID、表ID或列名。代码生成器读取本地配置文件,不会检查远程架构。过时的配置文件会生成过时的代码。
appwrite.config.json如果远程架构是可信来源,先执行更新配置文件。不要覆盖本地未推送的架构修改。如果本地配置文件更新更及时,可以直接基于它生成代码。
appwrite pull table对于TypeScript,优先使用。它会生成完整的TablesDB包装器:数据库和表选择、创建/更新负载、返回数据行、查询字段和查询值都会被TypeScript校验。这比仅生成模型接口更可靠。
appwrite generatebash
appwrite generate使用生成的API,不要退回到原始字符串ID和手写负载类型:
typescript
import { databases, type Songs } from "./generated/appwrite/index.js";
// 数据库查找使用ID;表查找使用配置文件中的名称。
const songs = databases.use("main").use("Songs");
const page = await songs.list({
queries: (query) => [
query.equal("published", true),
query.orderDesc("createdAt"),
query.limit(20),
],
});
const first: Songs | undefined = page.rows[0];不要猜测示例中的字面量:查看生成的类型或配置文件。特别注意,表的方法接受的是表的,可能与其不同。让编译过程检测拼写错误的表、列或错误的查询值。生成代码后运行项目的类型检查器。
.use()name$idgenerateAPPWRITE_API_KEYappwrite generate --help对于其他支持的语言,或项目刻意直接使用常规SDK时,使用。它支持TypeScript()、JavaScript()、PHP()、Kotlin()、Swift()、Java()、Dart()和C#()。请将这些短值传递给参数;或等名称不是命令接受的值。生成的文件会为行数据添加类型,但不会对原始数据库/表ID或调用进行类型校验:
appwrite types <output-directory>tsjsphpkotlinswiftjavadartcs--languagetypescriptcsharpQuery对于TypeScript,如果结果将作为模块导入,请传递目标路径。传递目录会在其中创建文件。
.tsappwrite.d.tsbash
appwrite types ./src/appwrite-types.ts --language tstypescript
import { Client, TablesDB } from "appwrite";
import type { Songs } from "./appwrite-types.js";
// 从appwrite.config.json读取这些值,并通过应用现有的配置机制暴露。
const client = new Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>");
const tablesDB = new TablesDB(client);
const page = await tablesDB.listRows<Songs>({
databaseId: "main", // 仍是未校验的字符串
tableId: "songs", // 仍是未校验的字符串
});不要将描述为“完全类型安全”。它仅会将字段名转换为目标语言的命名规范。当目标是获得完全类型化的TypeScript表API时,请使用。
types --strictgenerate生成的代码是衍生输出。不要通过修改生成代码来修复架构或命名问题;请修改或生成器输入后重新生成。每次修改表或列后,运行仓库中使用的生成命令,并执行格式化/类型检查。保留仓库现有的输出路径和提交规范。
appwrite.config.jsonFunctions and sites
函数与站点
Variables live in , not in . replaces the remote set from that file. Omit it unless you intend to sync secrets.
<path>/.envappwrite.config.json--with-variablesbash
undefined变量存储在中,而非。参数会替换远程端的变量集合。除非有意同步敏感信息,否则不要使用该参数。
<path>/.envappwrite.config.json--with-variablesbash
undefinedGood — ship code, leave remote vars alone
推荐操作 — 仅部署代码,保留远程变量
appwrite push function --function-id api --activate --force
appwrite push function --function-id api --activate --force
Bad — remote vars you did not list locally are gone
不推荐操作 — 本地未列出的远程变量会被删除
appwrite push function --function-id api --with-variables --force
appwrite push function --function-id api --with-variables --force
Good — deploy without switching live traffic
推荐操作 — 部署但不切换流量
appwrite push function --function-id api --activate=false --force
`--async` returns before the build finishes. Local: `appwrite run function`.appwrite push function --function-id api --activate=false --force
`--async`参数会在构建完成前返回结果。本地测试使用`appwrite run function`。Queries and output
查询与输出
Prefer , / , , , . is deprecated. only for Query JSON the flags cannot express.
--filter--sort-asc--sort-desc--limit--select--cursor-after--where--queriesbash
undefined优先使用、/、、、。已废弃。仅当标志无法表达复杂查询时才使用传递JSON格式的Query。
--filter--sort-asc--sort-desc--limit--select--cursor-after--where--queriesbash
undefinedGood
推荐操作
appwrite users list
--filter 'emailVerification=true'
--sort-desc '$createdAt'
--limit 20
--json
--filter 'emailVerification=true'
--sort-desc '$createdAt'
--limit 20
--json
appwrite users list
--filter 'emailVerification=true'
--sort-desc '$createdAt'
--limit 20
--json
--filter 'emailVerification=true'
--sort-desc '$createdAt'
--limit 20
--json
Bad
不推荐操作
appwrite users list --queries '[{"method":"equal","attribute":"emailVerification","values":[true]}]'
`--filter` parses `true` / `false` / `null`, numbers, and JSON arrays. Repeat the flag to AND. List pages cap at 100; prefer `--cursor-after <lastId>` over a large `--offset`.
`--json` for scripts (empty fields dropped). `--raw` for the unfiltered payload. Secrets stay redacted unless `--show-secrets`.appwrite users list --queries '[{"method":"equal","attribute":"emailVerification","values":[true]}]'
`--filter`可解析`true`/`false`/`null`、数字和JSON数组。重复该标志表示逻辑AND。列表分页上限为100条;优先使用`--cursor-after <lastId>`而非大数值的`--offset`。
脚本中使用`--json`(空字段会被忽略)。`--raw`用于获取未过滤的负载。敏感信息会被自动屏蔽,除非使用`--show-secrets`。The config file itself
配置文件本身
The CLI walks up from cwd looking for (or the legacy ). from still hits the project root. A stray config in a parent directory will capture you.
appwrite.config.jsonappwrite.jsonpushfunctions/api/Split large projects with — each value is a relative array. A resource cannot be both inline and included. Function and site values resolve relative to the include file, not the repo root.
includes.jsonpathDo not invent the file from memory. or writes a valid one. Then edit.
init projectpullCLI会从当前目录向上遍历查找(或旧版)。在目录执行push仍会找到项目根目录的配置文件。父目录中的无关配置文件可能会干扰操作。
appwrite.config.jsonappwrite.jsonfunctions/api/大型项目可使用拆分配置——每个值是相对路径的数组。资源不能同时存在于主配置和引入配置中。函数和站点的值相对于引入文件解析,而非仓库根目录。
includes.jsonpath不要凭记忆编写配置文件。或会生成有效的配置文件,之后再进行编辑。
init projectpull