跳转到内容
搜索文档

D1 Database

最后更新 查看 MarkdownAgent 设置

要从 Worker 与 D1 数据库交互,需要通过提供给 Worker 的环境绑定(env)访问它。

async fetch(request, env) {
	// D1 database is 'env.DB', where "DB" is the binding name from the Wrangler configuration file.
}
from workers import WorkerEntrypoint

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        # D1 database is 'self.env.DB', where "DB" is the binding name from the Wrangler configuration file.
        pass

D1 绑定的类型为 D1Database,支持以下多种方法。

方法

prepare()

准备查询语句以供后续执行。

const someVariable = `Bs Beverages`;
const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable);
some_variable = "Bs Beverages"
stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable)

参数

  • query: StringRequired
    • 您要在数据库上执行的 SQL 查询。

返回值

指南

如下所示,您可以使用 bind 方法动态将值绑定到查询语句中。

  • 不使用 bind 的静态语句示例:

    const stmt = db
    	.prepare("SELECT * FROM Customers WHERE CompanyName = 'Alfreds Futterkiste' AND CustomerId = 1")
    stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = 'Alfreds Futterkiste' AND CustomerId = 1")
  • 使用 bind 的有序语句示例:

    const stmt = db
    	.prepare("SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?")
    	.bind("Alfreds Futterkiste", 1);
    stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?").bind("Alfreds Futterkiste", 1)

有关更多信息,请参阅 bind 方法文档

batch()

在单次调用中向数据库发送多个 SQL 语句。这可以显著影响性能,因为它减少了与 D1 的网络往返延迟。D1 以自动提交模式运行。我们的实现保证列表中的每个语句按顺序、非并发地执行和提交。

批处理语句是 SQL 事务。如果序列中的语句失败,则返回该特定语句的错误,并中止或回滚整个序列。

要发送批处理语句,向 D1Database::batch 提供预编译语句列表,并按相同顺序获取结果。

const companyName1 = `Bs Beverages`;
const companyName2 = `Around the Horn`;
const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`);
const batchResult = await env.DB.batch([
	stmt.bind(companyName1),
	stmt.bind(companyName2)
]);
company_name1 = "Bs Beverages"
company_name2 = "Around the Horn"
stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?")
batch_result = await self.env.DB.batch([
    stmt.bind(company_name1),
    stmt.bind(company_name2),
])

参数

返回值

  • results: Array

返回值示例

const companyName1 = `Bs Beverages`;
const companyName2 = `Around the Horn`;
const stmt = await env.DB.batch([
	env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`).bind(companyName1),
	env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`).bind(companyName2)
]);
return Response.json(stmt)
from workers import Response

company_name1 = "Bs Beverages"
company_name2 = "Around the Horn"
stmt = await self.env.DB.batch([
    self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(company_name1),
    self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(company_name2),
])
return Response.json(stmt)
[
  {
    "success": true,
    "meta": {
      "served_by": "miniflare.db",
      "duration": 0,
      "changes": 0,
      "last_row_id": 0,
      "changed_db": false,
      "size_after": 8192,
      "rows_read": 4,
      "rows_written": 0
    },
    "results": [
      {
        "CustomerId": 11,
        "CompanyName": "Bs Beverages",
        "ContactName": "Victoria Ashworth"
      },
      {
        "CustomerId": 13,
        "CompanyName": "Bs Beverages",
        "ContactName": "Random Name"
      }
    ]
  },
  {
    "success": true,
    "meta": {
      "served_by": "miniflare.db",
      "duration": 0,
      "changes": 0,
      "last_row_id": 0,
      "changed_db": false,
      "size_after": 8192,
      "rows_read": 4,
      "rows_written": 0
    },
    "results": [
      {
        "CustomerId": 4,
        "CompanyName": "Around the Horn",
        "ContactName": "Thomas Hardy"
      }
    ]
  }
]
console.log(stmt[1].results);
print(stmt[1].results.to_py())
[
  {
    "CustomerId": 4,
    "CompanyName": "Around the Horn",
    "ContactName": "Thomas Hardy"
  }
]

指南

  • 您可以复用同一预编译语句构建批处理:

    const companyName1 = `Bs Beverages`;
    const companyName2 = `Around the Horn`;
    const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`);
    const batchResult = await env.DB.batch([
    	stmt.bind(companyName1),
    	stmt.bind(companyName2)
    ]);
    return Response.json(batchResult);
    from workers import Response
    
    company_name1 = "Bs Beverages"
    company_name2 = "Around the Horn"
    stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?")
    batch_result = await self.env.DB.batch([
        stmt.bind(company_name1),
        stmt.bind(company_name2),
    ])
    return Response.json(batch_result)

exec()

直接执行一个或多个查询,无需预编译语句或参数绑定。

const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
return_value = await self.env.DB.exec('SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"')

参数

  • query: StringRequired
    • 无参数绑定的 SQL 查询语句。

返回值

  • D1ExecResult: Object
    • count 属性包含已执行的查询数量。
    • duration 属性包含操作的持续时间(毫秒)。

返回值示例

const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
return Response.json(returnValue);
from workers import Response

return_value = await self.env.DB.exec('SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"')
return Response.json(return_value)
{
  "count": 1,
  "duration": 1
}

指南

  • 如果发生错误,将抛出包含查询和错误消息的异常,执行停止,后续语句不会执行。有关更多信息,请参阅错误
  • 此方法性能可能较差(预编译语句在某些情况下可复用),更重要的是,安全性较低。
  • 仅将此方法用于维护和一次性任务(例如,迁移作业)。
  • 输入可以是一个或多个由 \n 分隔的查询。

dump

将整个 D1 数据库转储到 ArrayBuffer 内的 SQLite 兼容文件。

const dump = await db.dump();
return new Response(dump, {
	status: 200,
	headers: {
		"Content-Type": "application/octet-stream",
	},
});
from workers import Response

dump = await db.dump()
return Response(dump, status=200, headers={"Content-Type": "application/octet-stream"})

参数

  • 无。

返回值

  • 无。

withSession()

启动 D1 会话,在返回的 D1DatabaseSession 对象上执行的查询之间保持顺序一致性。

const session = env.DB.withSession("<parameter>");
session = self.env.DB.withSession("<parameter>")

参数

  • first-primary: StringOptional

    • 将 Session 中的第一个查询(读取或写入)定向到主数据库实例。如果您需要使用主数据库实例的最新数据启动 Session,请使用此选项。
    • Session 中的后续查询可能使用读副本。
    • Session 中的后续查询具有顺序一致性。
  • first-unconstrained: StringOptional

    • 将 Session 中的第一个查询(读取或写入)定向到任何数据库实例。如果您不需要使用最新数据启动 Session,并希望从 Session 一开始就优先最小化查询延迟,请使用此选项。
    • Session 中的后续查询具有顺序一致性。
    • 未提供参数时的默认行为。
  • bookmark: StringOptional

    • 来自先前 D1 Session 的 bookmark。这允许您从至少提供的 bookmark 启动新 Session。
    • Session 中的后续查询具有顺序一致性。

返回值

  • D1DatabaseSession: Object

指南

  • 要使用读复制,您必须使用 D1 Sessions API,否则所有查询将继续仅由主数据库执行。
  • 您可以使用 session.getBookmark() 返回给定 Session 最后遇到的书签。

D1DatabaseSession 方法

getBookmark

从 D1 Session 检索最新的 bookmark

const session = env.DB.withSession("first-primary");
const result = await session
	.prepare(`SELECT * FROM Customers WHERE CompanyName = 'Bs Beverages'`)
	.run()
const { bookmark } = session.getBookmark();
	return bookmark;
session = self.env.DB.withSession("first-primary")
result = await session.prepare(
    "SELECT * FROM Customers WHERE CompanyName = 'Bs Beverages'"
).run()

bookmark = session.getBookmark()

参数

  • None

返回值

  • bookmark: String | null
    • bookmark,标识 Session 内最后执行的查询所看到的数据库最新版本。
    • 如果 Session 内未执行查询,则返回 null

prepare()

此方法等同于 D1Database::prepare

batch()

此方法等同于 D1Database::batch

这篇文档对您有帮助吗?