ByteNoteByteNote
绑定名要对应查询对象
字

字节笔记本

2026年10月7日 · 约 8 分钟读完

绑定名要对应查询对象

API中转
¥120

wrangler.toml 里的 D1 绑定有三项。binding 是你自己起的名字,代码里用它找库。database_name 是在控制台创建数据库时起的名字。database_id 是点进该库详情后看到的那串标识。三项不要互相代替。

绑定名自己起,库标识从详情页抄

名字和标识从两处来

对话里的配置是:

toml
[[d1_databases]]
binding = "DB"
database_name = "your-database-name"
database_id = "your-database-id"

binding 可以改成别的单词。改了之后,代码里引用的名字必须一起改。它不会出现在控制台的数据库列表里,因为它不是库的名字。

database_name 的取法按对话所说:进入 Workers 与 Pages,打开左侧的 D1,列表里的名称就是它。database_id 要点进这个库的详情,字段就叫 Database ID。把详情里的长字符串抄进 toml,不要把名称再填进 id 那一行。名称给人看,标识给绑定用。两个库可以同名的机会很小,但标识才是唯一的。抄错标识,部署可以成功,运行时绑定到另一份库,查询会打到空表。

控制台的 Pages 项目里,Functions 一段还要确认这份 D1 绑定开着。只写 toml、项目设置里没挂上,运行时拿不到 DB。

prepare 需要的是绑定对象

样本把运行时设成 edge,再从 process.env 里取出 DB,调用 DB.prepare("SELECT * FROM your_table").all()。prepare 是 D1 绑定对象上的方法。环境变量文件里的值是字符串。字符串上没有 prepare。若这里拿到的 DB 只是 toml 里的名字,调用会在取方法时失败,SQL 还没发出去。

绑定要到的是请求上下文里的那个对象,名字与 binding 一致。对话把取出的位置写成 process.env。这和“绑定不是一段 dotenv 文本”对不上。部署到 Pages 之后,用框架提供的请求上下文去读 binding 那个名字,确认它有 prepare,再执行 SELECT。表名 your_table 只是占位,库里没有这张表时,prepare 能调用,all 会返回数据库错误。先建表,再写这条查询。

runtime 设成 edge 是样本要求。绑在 Node 服务端函数上而运行时不是 edge,绑定对象也不会按 Pages Functions 的方式出现。先让这条路由的运行时和部署目标一致,再查名字是否抄对。

先确认对象上有 prepare

三项对齐再部署

binding 自己起,并在代码里用同一个名字。database_name 来自 D1 列表。database_id 来自详情页。Pages 的 Functions 设置里要挂上这个库。查询前确认拿到的是带 prepare 的对象,而不是同名的字符串。表要先存在。标识抄错时,失败表现为查错库或空表,不一定是配置文件语法错误。

三项抄错时的表现不同

把 binding 写成 DB,代码里却解构 DATABASE。运行时对象在 DB 上,DATABASE 是未定义。调用 prepare 会在取值时失败,SQL 没有发出。把 database_name 抄进 database_id 那一行,toml 语法仍然正确,绑定指向的不是详情页上的那份库。查询打到另一处或失败在库不存在。把详情页的 id 抄进 database_name,列表里对不上名称,创建绑定时就会被拒绝。三种错误不要用同一种“配置写错了”带过,先看失败出现在部署时还是第一次查询时。

SELECT * FROM your_table 里的表名是占位。库是空的,绑定对象已经有 prepare,all 仍会返回找不到表。先在这份 database_id 对应的库里建表,再执行样本查询。列名也要和表一致。样本没有给出列,不要假设有 id 或 name。

export const runtime = "edge" 写在使用绑定的那段路由上。别的路由仍是默认运行时,不会因为这一行变成 edge。只有声明了的那段才能按 Pages Functions 去拿绑定。把查询写在没有这行的文件里,再去 process.env 里找 DB,更容易拿到空。对话给出的解构位置是 process.env。绑定对象若只挂在请求上下文上,这个解构得到的不是带方法的对象。修正方式是改读取位置,而不是把 database_id 再写进环境变量文件。环境变量里的字符串没有 prepare。

Pages 项目的 Functions 设置要挂上同一份 D1。只改 toml、设置里没有,本地或预览可能和线上不一致。对一下三处:toml 的 binding、代码里的名字、项目设置里的库。三处同名同库之后,再跑 SELECT。

代码里的名字必须和 binding 逐字相同。写成 DB 就解构 DB。改成 UserDB,解构也要改成 UserDB。名称列表里看不到这个单词,因为它只存在于 toml 和代码之间。详情页上的 Database ID 是另一串,不要拿去当绑定名。

查询样本是 SELECT * FROM your_table。占位表名留在生产代码里,绑定正确也会报找不到表。先把表建成对话没有给出的真实表名,再替换这句 SQL。all 返回的行结构取决于表,样本没有列清单,页面不要假设固定字段。

runtime 那一行只作用于写了它的文件。邻近的路由没有这行,不会自动变成 edge,也拿不到同一份绑定。把查询复制到另一文件时,运行时声明和绑定名要一起复制。只复制 SQL,会在新文件里再次从环境变量里拆出一个没有 prepare 的值。

部署之后到 Pages 的 Functions 设置里核对 D1 是否挂上。toml 三项、设置里的库、代码里的名字,三处一致再发请求。标识抄错的失败常常是空结果或错库,语法检查发现不了。名称抄进标识那一行,会在创建绑定阶段被拒绝。先看失败发生在部署还是第一次查询。

字符串上调用 prepare 会在取方法时失败,SQL 还没到数据库。这时去改 database_id 没有用。先确认拿到的值的类型是对象,再核对标识。对象确认之后,才用详情页的 Database ID 去对 toml。顺序反了,会在两处同时改,分不清是哪一项生效。 把一次失败拆开看。部署日志若在创建绑定阶段就拒绝,优先核对 database_name 是否来自 D1 列表、database_id 是否来自详情页的 Database ID。部署成功但第一次 prepare 就抛错,优先看代码解构的名字是否等于 binding,以及拿到的是不是对象。all 能执行但结果为空,再查是不是标识指向了另一份空库,或 your_table 还没换成已存在的表。Pages 项目设置里的 Functions 没挂上这份库时,表现更像根本没有 DB,而不是 SQL 写错。四段不要同时改。改完一段就再请求一次,确认是哪一项从失败变成成功。

部署成功只说明配置文件能被读入,不说明查询会打到你点开的那一份库。名称来自列表,标识来自详情,绑定名由你自己起,三者各管一件事。代码里要拿到带查询方法的对象,不能把同名的一段文本当成库。运行时声明要写在真正发起查询的那个文件上。项目设置里的函数绑定要和配置文件指向同一份库。表名必须已经存在。空结果先怀疑标识和表名,方法调用失败先怀疑拿到的是不是对象。一次只改一项,再发一次查询,才能知道是哪一项生效。

相关文章

分享: