D1 客户端 API
D1 客户端 API 支持 :
- 发言稿和静态发言
- 元信息( 持续时间, 变化次数, LastRowId)
- 为更好的性能进行了多批次的 SQL 查询( 避免 HTTP 回合)
- 完整的数据库垃圾堆
- 发言稿续用
- 处理错误
D1是建立在 SQL 点 并使用 SQL 语言。 。 。 .
安装
npm install @cloudflare/d1 --save-dev
(原始内容存档于2018-03-26) (英语). wrangler.toml
在使用 API 之前, 您需要将此添加到您的项目中 (原始内容存档于2018-03-26) (英语). wrangler.toml数字 :
[[unsafe.bindings]]
name = "D1"
type = "cfsql"
database = "testdb"
导入 D1
将此添加到您的工人代码中 :
import { Database } from "@cloudflare/d1"; // this will be native at some point, see above
const db = new Database(env.D1);
你准备好用D1了
发言稿
编写语句是数据库用于运行 SQL 的预编译对象
客户端API支持静态或已准备的报表. 开发者被激励使用后者,因为他们导致总体执行更快,并且也防止了SQL注射攻击,但客户端API不会强迫它.
静态声明:
const stmt = db.prepare('SELECT * FROM users WHERE name = "John Doe"')
发言稿:
const stmt = db.prepare('SELECT * FROM users WHERE name = ?1').bind('Joe');
参数绑定
我们跟着 SQLite 公约 用于准备的声明参数具有约束力。 目前我们只支持命令(?NNNN)和匿名(?)参数. 今后,我们将支持指定的参数.
| 语法 | 类型 | 说明 |
|---|---|---|
| 没有 | 已订购 | 后有数字NNN的问号为NNN-th参数设置了点. NNN必须介于1到 SQLITE MAX VARIBAL Number之间. |
| ? 吗? | 无名 | 一个没有数字后面的问号会创建一个参数,一个数字比已经指派的最大参数数大. 如果这意味着参数数大于 SQLITE MAX VARIABLE NUMBER,则是一个错误. 提供这个参数格式是为了与其他数据库引擎兼容. 但由于容易错误地计算出问号,因此这种参数格式的使用被劝阻. 鼓励程序员使用下面的符号格式或上面的?NNNN格式. |
要绑定一个参数,我们使用这个方法 stt.bind () (中文(简体) )
秩序和匿名例子:
const stmt = db.prepare('SELECT * FROM users WHERE name = ?').bind( 'John Doe' );
const stmt = db.prepare('SELECT * FROM users WHERE name = ? AND age = ?').bind( 'John Doe', 41 );
const stmt = db.prepare('SELECT * FROM users WHERE name = ?2 AND age = ?1').bind( 41, 'John Doe' );
类型转换
这就是我们如何将 Javascript 输入转换为 D1 输入:
| D1级 | Javascript |
|---|---|
| 无效 | 无效 |
| 真实 | 数目 |
| 进口 | 编号 [^1] |
| 文本 | 字符串 |
| 块 | 矩阵缓冲 |
[^1]:D1在内部支持64位签名的INTEGERs,然而我们不支持 大点 在API 还没有。 Javascript 整数安全到 号码.MAX SAFE INTEGER。 。 。 .
返回对象
Stmt.run()、stmt.all()和db.batch()的方法返回包含结果的对象, 上一页 (如果适用),写作变化的次数和操作的内部持续时间以毫秒计.
{
results: array, // [] if empty
lastRowId: integer, // the rowid of the last row inserted or null if it doesn't apply
changes: integer, // total number of rows that were inserted, updated, or deleted, or 0 if read-only
duration: integer, // duration of the operation in milliseconds
}
示例
const { lastRowId } = await db.prepare('INSERT INTO users (name, age) VALUES (?1, ?2)').bind( "John", 42 ).run();
console.log(lastRowId); // 72
查询语句方法
D1 API支持以下查询语句方法.
等待stt. first( [栏 )
返回结果的第一行.
从第一行获取一个特定的列 :
const stmt = db.prepare('SELECT COUNT(*) AS total FROM users');
const total = await stmt.first('total');
console.log(total); // 50
从第一行取出所有列 :
const stmt = db.prepare('SELECT COUNT(*) AS total FROM users');
const values = await stmt.first();
console.log(values); // { total: 50 }
正在等待stt.all () (中文(简体) )
返回所有行和元数据.
const stmt = db.prepare('SELECT name, age FROM users LIMIT 3');
const { results } = await stmt.all();
console.log(results);
/*
[
{
name: "John",
age: 42,
},
{
name: "Anthony",
age: 37,
},
{
name: "Dave",
age: 29,
},
]
*/
正在等待 stmt.raw ()
与 stmt.all () 相同, 但返回一组行而不是对象 .
const stmt = db.prepare('SELECT name, age FROM users LIMIT 3');
const raw = await stmt.raw();
console.log(raw);
/*
[
[ "John", 42 ],
[ "Anthony", 37 ],
[ "Dave", 29 ],
]
*/
console.log(rows.map(row => row.join(',')).join("\n"));
/*
John,42
Anthony,37
Dave,29
*/
正在等待stt.run () ()
运行查询/查询,但没有返回结果。 相反,运行()只返回测量值.
用于UpDate,DEELETE或INSERT等写入操作.
const info = await db.prepare('INSERT INTO users (name, age) VALUES (?1, ?2)')
.bind( "John", 42 )
.run()
console.log(info);
/*
{
lastRowId: 56
changes: 1
duration: 62
}
*/
等待 db.dump( ) ()
将整个 D1 数据库丢入 Array Buffer 中的 SQLite Compatibile 文件 .
const dump = await db.dump()
return ( new Response(dump, {
status: 200,
headers: {
'Content-Type': 'application/octet-stream'
}
} );
正在等待 db.exec ()
直接执行一次或多次询问,而不准备的声明或参数具有约束力。 这种方法的性能可能较差(在某些情况下,准备的语句可以被再用),更重要的是,安全性更差. 只用这种方法进行维护和一发任务(例如:迁移活计). 输入可以是由\n分隔的一个或多个查询.
如果出现出错,则会随查询和出错消息一起抛出一个例外(见下文"出错"),执行停止和进一步语句不会被执行.
const migration = await fetch('/migration.sql');
const out = await db.exec(migration.text());
console.log(out);
/*
{
count: 80,
duration: 7655
}
*/
重用已准备好的报表
发言稿可重新使用新的装订:
const stmt = db.prepare('SELECT name, age FROM users WHERE age < ?1');
const young = await stmt.bind(20).all();
console.log(young);
/*
{
results: [...],
lastRowId: 0
changes: 0
duration: 31
}
*/
const old = await stmt.bind(80).all();
console.log(old);
/*
{
results: [...],
lastRowId: 0
changes: 0
duration: 29
}
*/
批量语句
Batching将一个单调内多个SQL语句发送到数据库. 这可以产生巨大的性能影响,因为它会把从网络回转到D1的间歇性降低. 请注意,批量报表不是真实的SQL交易. D1以自动承诺方式运行. 我们的执行保证,清单上的每一项声明将按顺序执行,并同时执行.
批注语句不是 SQL 交易如果序列中的语句失败,则返回该特定语句的错误,则不会中止或回滚整个序列.
db.batch () (中文(简体) )
要发送批量语句,我们将批量()输入已准备好语句的清单,并按同样的顺序得到结果.
await db.batch([
db.prepare("UPDATE users SET name = ?1 WHERE id = ?2").bind( "John", 17 ),
db.prepare("UPDATE users SET age = ?1 WHERE id = ?2").bind( 35, 19 ),
]);
您可以重用同样的制备语句构建批次:
const stmt = db.prepare("SELECT * FROM users WHERE name = ?1");
const rows = await db.batch([
stmt.bind("John"),
stmt.bind("Anthony"),
]);
console.log(rows[0].results);
/*
[
{
name: "John Clemente",
age: 42,
},
{
name: "John Davis",
age: 37,
},
]
*/
console.log(rows[1].results);
/*
[
{
name: "Anthony Hopkins",
age: 66,
},
]
*/
PRAGMA声明
D1支持以下内容: SQLite 普拉马 语句 :
| 巴布亚新几内亚 | 说明 |
|---|---|
| 表格列表( l) | 返回图中的表格和视图信息,每行输出一个表格. |
| 表格( n) | 此 pragma 返回指定表格中每个列的一行 。 结果集中的列包括列名,数据类型,列是否可以是NULL,以及列的默认值. |
| 外国键 | 查询、设置或清除外国关键限制的执行. |
其他PRAGMA由于D1执行细节被禁用.
示例
const r = await db.batch([
db.prepare("PRAGMA table_list"),
db.prepare("PRAGMA table_info(my_table)"),
]);
console.log(r);
/*
[
{
"results": [
{
"schema": "main",
"name": "my_table",
"type": "table",
"ncol": 3,
"wr": 0,
"strict": 0
},
...
]
},
{
"results": [
{
"cid": 0,
"name": "cid",
"type": "INTEGER",
"notnull": 0,
"dflt_value": null,
"pk": 1
},
...
]
}
]
*/
错误
T. db. 方法将推出 错误对象 当错误发生时.
D1 Javascript 错误使用 原因属性 详细情况.
new Error("D1_ERROR", { cause: new Error("Error detail") })
要捕捉例外:
try {
await db.exec("INSERTZ INTO my_table (name, employees) VALUES ()");
} catch (e: any) {
console.log({
message: e.message,
cause: e.cause.message,
});
}
/*
{
"message": "D1_EXEC_ERROR",
"cause": "Error in line 1: INSERTZ INTO my_table (name, employees) VALUES (): sql error: near \"INSERTZ\": syntax error in INSERTZ INTO my_table (name, employees) VALUES () at offset 0"
}
*/
错误列表
| 消息 | 原因 |
|---|---|
| D1 错误 | 常规错误 |
| D1 诺斯 | 无结果 |
| D1 COLMN NOTFOUND (英语) | 未找到列 |
| D1 DUMP 错误 | 数据库堆放出错 |
| D1 EXEC 错误 | 在行x中执行错误:y 错误 |
实例
你可以找到一个D1"Hello World"的例子 这里。 。 。 .