← Cloudflare D1 / d1 / best-practices
Импорт и экспорт данных
D1 позволяет напрямую импортировать существующие таблицы SQLite вместе с данными, благодаря чему перенос данных в D1 занимает мало времени и не вызывает сложностей. Это может пригодиться при переносе приложений на Workers и D1 или когда вы хотите сначала спроектировать схему локально, прежде чем импортировать её в базы данных D1.
D1 также позволяет экспортировать базу данных. Это может быть полезно для локальная разработка или тестирования.
Импорт существующей базы данных
Чтобы импортировать существующую базу данных SQLite в D1, у вас должно быть:
- Cloudflare Установлен Wrangler CLI.
- База данных, которая будет использована как целевая.
- Существующий файл базы данных SQLite (версии 3.0 и выше) для импорта.
Например, рассмотрим следующий users_export.sql схему и значения, которые включают 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 файл в текущем рабочем каталоге, вы можете передать --file=users_export.sql флаг для d1 execute чтобы выполнить (импортировать) схему таблицы и значения:
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.
Например, если у вас есть исходный дамп SQLite с именем db_dump.sqlite3, выполните следующее sqlite команду, чтобы преобразовать его:
sqlite3 db_dump.sqlite3 .dump > db.sqlПосле выполнения указанной выше команды вам нужно будет отредактировать полученный SQL-файл, чтобы он стал совместим с D1:
- Удалить
BEGIN TRANSACTIONиCOMMIT;из файла - Удалите следующий оператор создания таблицы (если он присутствует):
CREATE TABLE _cf_KV ( key TEXT PRIMARY KEY, value BLOB ) WITHOUT ROWID;
После этого выполните шаги, чтобы импорт существующей базы данных в D1 с помощью .sql файл, сгенерированный из дампа базы данных, в качестве входных данных для wrangler d1 execute.
Экспорт существующей базы данных D1
Помимо импорта существующих баз данных SQLite, может понадобиться экспортировать базу данных D1 для локальной разработки или тестирования. Базу данных D1 можно экспортировать в .sql файл с помощью wrangler d1 export а затем выполнить (импортировать) с помощью d1 execute --file.
Чтобы экспортировать полную схему и данные базы данных D1:
npx wrangler d1 export <database_name> --remote --output=./database.sqlЧтобы экспортировать схему и данные одной таблицы:
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./table.sqlЧтобы экспортировать только схему базы данных D1:
npx wrangler d1 export <database_name> --remote --output=./schema.sql --no-dataЧтобы экспортировать только схему таблицы D1:
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 ↗. В качестве обходного решения удалите все виртуальные таблицы, выполните экспорт, а затем создайте виртуальные таблицы заново.
- Выполняющийся экспорт блокирует другие запросы к базе данных.
- На любое числовое значение в столбце влияет 52-битная точность чисел в JavaScript. Если вы сохраните очень большое число (в
int64), а затем получить то же значение, возвращённое значение может быть менее точным, чем исходное число.
Устранение неполадок
Если при попытке импортировать существующую схему и (или) набор данных в D1 возникает ошибка:
- Убедитесь, что импортируете данные в формате SQL (обычно с
.sqlрасширением файла). См. как преобразовать файлы SQLite если у вас есть.sqlite3дамп базы данных. - Убедитесь, что схема SQLite3 ↗ совместим. Импортировать данные из базы данных MySQL или PostgreSQL в D1 нельзя, так как типы и синтаксис SQL не полностью совместимы.
- Если между таблицами есть связи по внешним ключам, убедитесь, что импортируете таблицы в правильном порядке. Ссылаться на еще не существующую таблицу нельзя.
- Если вы получаете
"cannot start a transaction within a transaction"ошибку, убедитесь, что вы удалилиBEGIN TRANSACTIONиCOMMITиз выгруженных SQL выражений.
Устраните Statement too long ошибка
Если вы столкнётесь с Statement too long ошибку при попытке импортировать большой SQL-файл в D1, это означает, что один из 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.
Дальнейшие шаги
- Прочтите SQLite
CREATE TABLE↗ документация. - Узнайте, как используйте D1 Workers Binding API изнутри Worker.
- Узнайте, как работают миграции базы данных с D1.