跳转到内容
搜索文档

导入和导出数据

最后更新 查看 MarkdownAgent 设置

D1 允许您直接导入现有 SQLite 表及其数据,从而快速轻松地将现有数据迁移到 D1。这在将应用迁移到 Workers 和 D1 时很有用,或在将 schema 导入 D1 数据库之前先在本地进行原型设计时也很实用。

D1 也允许您导出数据库。这对于本地开发或测试很有用。

导入现有数据库

要将现有 SQLite 数据库导入 D1,您需要:

  1. 已安装 Cloudflare Wrangler CLI
  2. 一个用作目标的数据库。
  3. 一个要导入的现有 SQLite(3.0 及以上版本)数据库文件。

例如,考虑以下 users_export.sql schema 和数据,其中包含 CREATE TABLE IF NOT EXISTS 语句:

CREATE TABLE IF NOT EXISTS users (
	id VARCHAR(50),
	full_name VARCHAR(50),
	created_on DATE
);
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCN9519NRVXWTPG0V0BF', 'Catlaina Harbar', '2022-08-20 05:39:52');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNBYBGX2GC6ZGY9FMP4', 'Hube Bilverstone', '2022-12-15 21:56:13');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNCWAJWRQWC2863MYW4', 'Christin Moss', '2022-07-28 04:13:37');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNDGQNBQAJG1AP0TYXZ', 'Vlad Koche', '2022-11-29 17:40:57');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNF67KV7FPPSEJVJMEW', 'Riane Zamora', '2022-12-24 06:49:04');

users_export.sql 文件放在当前工作目录中,您可以向 d1 execute 传递 --file=users_export.sql 标志来执行(导入)表 schema 和数据:

npx wrangler d1 execute example-db --remote --file=users_export.sql

要确认表已正确导入且可查询,执行 SELECT 语句以从 D1 数据库中获取所有表:

npx wrangler d1 execute example-db --remote --command "SELECT name FROM sqlite_schema WHERE type='table' ORDER BY name;"
...
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.3165ms
┌────────┐
 name
├────────┤
 _cf_KV
├────────┤
 users
└────────┘

从这里,您可以从 Worker 使用 D1 Workers Binding API 查询新表。

转换 SQLite 数据库文件

如果您有来自其他系统的现有 SQLite 数据库,可以将其表导入 D1 数据库。使用 sqlite 命令行工具,您可以将 .sqlite3 文件转换为一组 SQL 语句,然后对 D1 数据库执行(导入)。

例如,如果您有一个名为 db_dump.sqlite3 的原始 SQLite 转储,运行以下 sqlite 命令进行转换:

sqlite3 db_dump.sqlite3 .dump > db.sql

运行上述命令后,您需要编辑输出的 SQL 文件以使其与 D1 兼容:

  1. 从文件中删除 BEGIN TRANSACTIONCOMMIT;
  2. 删除以下表创建语句(如果存在):
    CREATE TABLE _cf_KV (
     	key TEXT PRIMARY KEY,
     	value BLOB
    ) WITHOUT ROWID;

然后,您可以使用从数据库转储生成的 .sql 文件作为 wrangler d1 execute 的输入,按照导入现有数据库的步骤将其导入 D1。

导出现有 D1 数据库

除了导入现有 SQLite 数据库外,您可能还想导出 D1 数据库以进行本地开发或测试。您可以使用 wrangler d1 export 将 D1 数据库导出为 .sql 文件,然后使用 d1 execute --file 执行(导入)。

导出完整 D1 数据库 schema 和数据:

npx wrangler d1 export <database_name> --remote --output=./database.sql

导出单个表的 schema 和数据:

npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./table.sql

仅导出 D1 数据库 schema:

npx wrangler d1 export <database_name> --remote --output=./schema.sql --no-data

仅导出 D1 表 schema:

npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./schema.sql --no-data

仅导出 D1 数据库数据:

npx wrangler d1 export <database_name> --remote --output=./data.sql --no-schema

仅导出 D1 表数据:

npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./data.sql --no-schema

已知限制

  • 不支持导出虚拟表,包括包含虚拟表的数据库。D1 支持使用 SQLite 的 FTS5 模块进行全文搜索的虚拟表。作为变通方法,删除所有虚拟表,导出后再重新创建虚拟表。
  • 正在运行的导出会阻塞其他数据库请求。
  • 列中的任何数值都会受到 JavaScript 52 位数字精度的影响。如果您存储了一个非常大的数字(int64),然后检索相同的值,返回的值可能比原始数字精度更低。

故障排除

如果在尝试将现有 schema 和/或数据集导入 D1 时收到错误:

  • 确保您导入的是 SQL 格式数据(通常使用 .sql 文件扩展名)。如果您有 .sqlite3 数据库转储,请参阅如何转换 SQLite 文件
  • 确保 schema 与 SQLite3 兼容。您无法将 MySQL 或 PostgreSQL 数据库的数据导入 D1,因为类型和 SQL 语法不直接兼容。
  • 如果表之间存在外键关系,请确保按正确顺序导入表。您不能引用尚不存在的表。
  • 如果收到 "cannot start a transaction within a transaction" 错误,请确保已从转储的 SQL 语句中删除 BEGIN TRANSACTIONCOMMIT

解决 Statement too long 错误

如果在尝试将大型 SQL 文件导入 D1 时遇到 Statement too long 错误,这意味着文件中的某个 SQL 语句超过了允许的最大长度。

要解决此问题,将单个大型 INSERT 语句转换为多个较小的 INSERT 语句。例如,不要在一个语句中插入 1,000 行,而是将其拆分为四组,每组 250 行,如下面的代码所示。

之前:

INSERT INTO users (id, full_name, created_on)
VALUES
  ('1', 'Jacquelin Elara', '2022-08-20 05:39:52'),
  ('2', 'Hubert Simmons', '2022-12-15 21:56:13'),
  ...
  ('1000', 'Boris Pewter', '2022-12-24 07:59:54');

之后:

INSERT INTO users (id, full_name, created_on)
VALUES
  ('1', 'Jacquelin Elara', '2022-08-20 05:39:52'),
  ...
  ('100', 'Eddy Orelo', '2022-12-15 22:16:15');
...
INSERT INTO users (id, full_name, created_on)
VALUES
  ('901', 'Roran Eroi', '2022-08-20 05:39:52'),
  ...
  ('1000', 'Boris Pewter', '2022-12-15 22:16:15');

外键约束

导入数据时,您可能需要临时禁用外键约束。为此,在进行会违反外键的更改之前调用 PRAGMA defer_foreign_keys = true

请参阅外键文档,了解如何使用外键和 D1。

后续步骤

这篇文档对您有帮助吗?