介绍
支持团队需要能够筛选和更新记录,同时确保每条工单都能被准确区分。Cloudflare D1 是一种托管数据库,它将相关信息存储在表中,并接受用于描述所需数据的 SQL。表的结构类似电子表格:每一行代表一条工单,带名称的列保存工单字段。
开始本课程前,请先完成 将 LabEx 连接到你的 Cloudflare 账户。 该实验会介绍 LabEx VM 终端、设备授权、账户确认,以及保存实际账户 ID 的方法。直接进入本实验的学习者必须先完成该实验。你还应了解基本的 JavaScript Worker;本实验不要求 SQL 知识。
你将创建一个数据库,为有效工单定义规则,并区分本地练习记录和云端记录。本实验需要一个可随时删除的 D1 数据库,不需要部署 Worker。
请使用自己的学习账户和全新的 VM。初始化过程会先准备 Node.js 22.22.0,然后在 /home/labex/project/ticket-database 下运行 npm install,安装项目本地的 Wrangler 4.131.1 以及评测所需的依赖。直接依赖的版本已固定,安装过程会创建专用的锁定文件。初始化阶段不会执行云端登录或评测数据库操作。在个人计算机上操作时,请在项目中使用 npm install --save-dev wrangler@4.131.1 安装相同版本的 Wrangler。
本练习使用 D1 免费额度内的小型合成记录。现有账户用量也会计入这些额度。不需要购买域名。请保留此 VM,直到确认资源删除和退出登录都已完成。
授权此 VM 并选择账户
本步骤会将这个全新的终端连接到你自己的学习账户。仅登录 Dashboard 并不能授权此 VM。D1 权限允许创建数据库、修改 SQL 和删除数据库。授权前,请查看实际的同意页面,包括 Background Access。
打开已准备好的项目并检查固定的 CLI 版本:
cd /home/labex/project/ticket-database
npx wrangler --version
应显示 4.131.1。启动设备授权;--device 会显示浏览器验证码,--browser=false 会让你自行决定是否打开浏览器:
npx wrangler login --device --browser=false --scopes account:read user:read d1:write
在浏览器中打开终端显示的 URL,输入当前验证码,确认学习账户和权限,然后完成授权。等待终端确认授权成功。不要将密码或令牌粘贴到项目文件中。

此示例显示了 D1 Write、账户访问权限以及必需的后台访问权限。授权前,请确认你选择的是自己的学习账户。
npx wrangler whoami --json
检查 loggedIn: true,然后读取账户的 name 和 id,即使列表中只有一个账户也不要省略。将目标账户的 ID 复制到下面的配置中。下面的 Shell 变量使用 6 个随机字节(12 个十六进制字符),以避免与其他学习者的名称冲突。此处的 here-document 会将 JSON 标记之间的内容写入文件;其中的 $RUN 会展开。
$schema 前的反斜杠会保留这个 JSON 键的原样;$RUN 仍会展开为本次运行的唯一名称。
RUN=labex-c04-d01-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
"\$schema": "./node_modules/wrangler/config-schema.json",
"name": "$RUN",
"account_id": "YOUR_ACCOUNT_ID",
"main": "src/index.js",
"compatibility_date": "2026-09-15",
"workers_dev": true,
"preview_urls": false
}
JSON
运行此代码块前,将 YOUR_ACCOUNT_ID 替换为实际账户 ID。保持此终端打开,以便 RUN 变量继续可用。name 用于标识本次运行;account_id 用于选择执行云端操作的账户。该文件是普通 JSON,同时也是有效的 JSONC。写入此文件不会部署 Worker。
创建本地工单表
本步骤会定义一个 schema:由数据库强制执行的列和规则。先创建云端容器及其绑定,但先将第一次 SQL 修改保留在本地。
创建一个可随时删除的云端数据库。--binding DB 为应用代码提供简短名称,--update-config 会将数据库的实际名称和 UUID 写入 wrangler.jsonc,--use-remote=false 则确保开发操作在本地进行:
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
读取创建出的名称和 ID,然后检查保存的绑定配置:
cat wrangler.jsonc
DB 条目必须指向本次运行创建的数据库。绑定是代码与资源之间经过配置的连接。它的 UUID 用于标识云端数据库,而 --local 使用的是此 VM 中独立的 SQLite 数据库。执行 SQL 命令时,必须始终明确指定 --local 或 --remote。
CREATE TABLE 用于定义表。INTEGER PRIMARY KEY 为每一行提供唯一的数字标识。TEXT 用于存储字符串。NOT NULL 禁止缺少值,CHECK 会拒绝不符合规则的值。插入数据时,如果省略某个字段,DEFAULT 会提供默认值。这些检查有助于避免工单信息不完整。
将 schema 和两条合成记录写入 SQL 文件。加引号的 SQL 标记会阻止 Shell 解释其中的内容。SQL 语句以分号结尾。INSERT INTO 会将列名与每一行中的值对应起来:
cat > schema.sql <<'SQL'
CREATE TABLE tickets (
id INTEGER PRIMARY KEY,
subject TEXT NOT NULL CHECK(length(trim(subject)) > 0),
status TEXT NOT NULL DEFAULT 'open' CHECK(status IN ('open','closed')),
source TEXT NOT NULL
);
INSERT INTO tickets (id, subject, status, source) VALUES
(1, 'Cannot sign in', 'open', 'seed'),
(2, 'Invoice copy', 'closed', 'seed');
SQL
仅将该文件应用到本地数据库:
npx wrangler d1 execute DB --local --file schema.sql
命令成功后,应报告已在本地数据库中执行。这并不能证明远程数据库中存在任何表。使用 SQLite 的 PRAGMA table_info 检查列定义:
npx wrangler d1 execute DB --local --command "PRAGMA table_info(tickets);"
应看到 id、subject、status 和 source。pk 字段表示主键,notnull 表示必填值。
筛选、更新和删除本地记录
本步骤会练习基本 SQL,并保留一个仅存在于本地的标记。SELECT 选择列,FROM 指定表,WHERE 筛选匹配的行,ORDER BY 使结果顺序保持可预测。
npx wrangler d1 execute DB --local --command "SELECT id, subject FROM tickets WHERE status = 'open' ORDER BY id;"
结果应为工单 1,即 Cannot sign in。SQL 字符串使用单引号,并放在命令的双引号内。添加一条本地练习工单:
npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source) VALUES (3, 'Local rehearsal', 'local');"
UPDATE 会修改匹配的行。执行前必须检查 WHERE 条件:如果省略它,所有行都会被修改。
npx wrangler d1 execute DB --local --command "UPDATE tickets SET status = 'closed' WHERE id = 3;"
尝试写入无效状态,观察约束如何保护数据:
npx wrangler d1 execute DB --local --command "UPDATE tickets SET status = 'lost' WHERE id = 3;"
此命令预期会失败。你应看到 CHECK constraint failed 消息,而不是身份验证或网络错误。该行仍应保持为 closed。创建并删除一条临时记录;DELETE 只会删除符合其谓词的行:
npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source) VALUES (4, 'Temporary', 'local'); DELETE FROM tickets WHERE id = 4;"
读取剩余记录:
npx wrangler d1 execute DB --local --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
应看到 ID 1、2 和 3;工单 3 的状态是 closed,来源是 local。工单 4 不应存在。失败的更新不能改变原本有效的记录。
初始化并检查远程数据库
本步骤会将相同的 schema 应用到云端数据库,并证明本地修改不会自动同步到云端。--remote 会将这些 SQL 语句发送到所选账户中的数据库 UUID。
npx wrangler d1 execute DB --remote --file schema.sql
如果出现提示,只确认本实验使用的数据库。添加一条仅存在于远程数据库的记录,它使用与本地练习记录相同的 ID,但数据不同:
npx wrangler d1 execute DB --remote --command "INSERT INTO tickets (id, subject, source) VALUES (3, 'Cloud inbox', 'remote');"
分别明确读取两个目标:
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
npx wrangler d1 execute DB --local --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
远程工单 3 的内容是 Cloud inbox,状态是 open,来源是 remote;本地工单 3 仍是 Local rehearsal,状态是 closed,来源是 local。这个差异证明你选择了预期的目标。
在 Cloudflare Dashboard 中选择同一账户,然后打开 Storage & databases → D1 SQLite Database。找到本次运行创建的准确数据库名称,并打开其详情页。将数据库 ID 与 wrangler.jsonc 中的值进行比较。如果页面提供只读表视图,请使用它检查 tickets。不要在那里创建或编辑记录。上面的 SQL 响应才是行内容的依据;Metrics 中延迟更新的计数不代表验证结果。
删除数据库前,先完成本步骤的验证。

打开 Explore Data,然后在 Studio 中选择 tickets,只查看数据,不编辑。截图中的随机数据库名属于一次测试运行,你的名称会不同。工单 3 是 Cloud inbox,来源为 remote;本地数据库仍是 Local rehearsal,来源为 local。
删除临时资源
本步骤会在 VM 仍处于授权状态时,只删除本实验创建的资源。请先完成所有功能检查。在确认删除完成前,保留配置文件。
npx wrangler d1 delete DB
检查提示内容,只确认本次运行创建的数据库。然后列出数据库:
npx wrangler d1 list --json
成功响应中不应再出现你记录的数据库名称和 UUID。其他资源可以保留。身份验证或网络错误无法证明删除成功:请先解决访问问题,然后重新执行读取操作再继续。仍处于登录状态时,完成本步骤的验证。
结束此 VM 的授权
本步骤会在独立的删除检查通过后结束授权。退出登录会删除此 VM 中保存的 Wrangler 授权信息;仅关闭 VM 并不能完成云端清理。
npx wrangler logout
npx wrangler whoami --json
应看到 loggedIn: false。未通过身份验证的查询可能以非零状态退出;只有当结构化响应明确表示你已退出登录时,这种结果才是预期的。完成验证后,关闭实验环境。
总结
你练习了创建支持工单数据库,检查了可观察的数据库结果,明确区分了所选账户和本地状态,并在退出登录前删除了临时资源。



