跳转到内容
搜索文档

导入和导出数据

最后更新 查看 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 TRANSACTION 和 COMMIT;
  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 TRANSACTION 和 COMMIT。

解决 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。

后续步骤

这篇文档对您有帮助吗?