Введение
Команде поддержки нужны записи, которые можно фильтровать и обновлять, не теряя связь с конкретной заявкой. Cloudflare D1 — это управляемая база данных, которая хранит связанные данные в таблицах и принимает SQL — язык для описания нужных данных. Таблица похожа на электронную таблицу: каждая строка представляет одну заявку, а именованные столбцы содержат её поля.
Перед началом этого курса пройдите лабораторную работу Подключение LabEx к вашей учётной записи Cloudflare. В ней показаны терминал виртуальной машины LabEx, авторизация устройства, подтверждение учётной записи и сохранение фактического идентификатора учётной записи. Если вы выполняете лабораторную работу напрямую, сначала пройдите именно её. Также вам нужно понимать основы небольшого JavaScript Worker; знание SQL здесь не требуется.
Вы создадите базу данных, определите правила для корректных заявок и научитесь отличать локальные записи для практики от облачных записей. Для этой лабораторной работы нужна одна временная база данных D1 и не требуется развёрнутый Worker.
Используйте собственную учебную учётную запись и новую виртуальную машину. Сначала настройка подготовит Node.js 22.22.0, затем выполнит npm install для локального Wrangler 4.131.1 и зависимостей проверки в каталоге /home/labex/project/ticket-database. Версии прямых зависимостей зафиксированы; установка создаёт собственный lock-файл. Во время настройки вход в облако и проверка базы данных не выполняются. На личном компьютере установите ту же версию Wrangler командой npm install --save-dev wrangler@4.131.1 в каталоге проекта.
В этом упражнении используются небольшие синтетические записи в пределах бесплатных лимитов D1. Текущее использование учётной записи также учитывается в этих лимитах. Покупать домен не нужно. Не закрывайте эту виртуальную машину, пока не проверите удаление ресурсов и выход из учётной записи.
Авторизуйте эту виртуальную машину и выберите учётную запись
На этом шаге вы подключите новый терминал к собственной учебной учётной записи. Одного входа в Dashboard недостаточно для авторизации виртуальной машины. Разрешение D1 позволяет создавать базы данных, изменять SQL и удалять базы данных. Перед авторизацией просмотрите фактическую страницу согласия, включая разрешение Background Access.
Откройте подготовленный проект и проверьте зафиксированную версию CLI:
cd /home/labex/project/ticket-database
npx wrangler --version
Ожидаемый результат — 4.131.1. Запустите авторизацию устройства. Параметр --device выводит код для браузера, а --browser=false позволяет вам самостоятельно выбрать способ открытия браузера:
npx wrangler login --device --browser=false --scopes account:read user:read d1:write
Откройте показанный URL в браузере, введите текущий код, подтвердите свою учебную учётную запись и разрешения, затем выполните авторизацию. Дождитесь подтверждения успешного завершения в терминале. Никогда не вставляйте пароли или токены в файлы проекта.

В этом примере разрешение D1 Write указано вместе с доступом к учётной записи и обязательным фоновым доступом. Перед авторизацией убедитесь, что выбрана именно ваша учебная учётная запись.
npx wrangler whoami --json
Проверьте значение loggedIn: true, затем прочитайте name и id учётной записи, даже если в списке указана только одна учётная запись. Скопируйте нужный идентификатор в конфигурацию ниже. Следующая переменная оболочки использует 6 случайных байт (12 шестнадцатеричных символов), чтобы избежать совпадений с другими учащимися. Here-document записывает JSON между строками JSON; переменная $RUN раскрывается внутри него.
Обратная косая черта перед $schema сохраняет этот ключ JSON буквально; $RUN по-прежнему подставляет уникальное имя текущего запуска.
RUN=labex-c04-d01-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
"\$schema": "./node_modules/wrangler/config-schema.json",
"name": "$RUN",
"account_id": "YOUR_ACCOUNT_ID",
"main": "src/index.js",
"compatibility_date": "2026-09-15",
"workers_dev": true,
"preview_urls": false
}
JSON
Перед выполнением блока замените YOUR_ACCOUNT_ID. Не закрывайте этот терминал, чтобы переменная RUN оставалась доступной. Поле name идентифицирует этот запуск, а account_id выбирает учётную запись для облачных операций. Файл содержит обычный JSON, который также является корректным JSONC. При его создании Worker не разворачивается.
Создайте локальную таблицу заявок
На этом шаге вы определите схему — столбцы и правила, которые применяет база данных. Сначала создайте облачный контейнер и его binding, но первые изменения SQL оставьте локальными.
Создайте временную облачную базу данных. Параметр --binding DB задаёт короткое имя для кода, --update-config записывает её настоящее имя и UUID в wrangler.jsonc, а --use-remote=false оставляет разработку локальной:
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
Прочитайте созданные имя и идентификатор, затем проверьте сохранённый binding:
cat wrangler.jsonc
Запись DB должна указывать базу данных этого запуска. Binding — это настроенное соединение между кодом и ресурсом. Его UUID идентифицирует облачную базу данных, а параметр --local использует отдельную базу SQLite на этой виртуальной машине. В командах SQL всегда явно указывайте --local или --remote.
Команда CREATE TABLE создаёт таблицу. INTEGER PRIMARY KEY задаёт каждой строке уникальный числовой идентификатор. TEXT хранит строки. NOT NULL запрещает пропущенные значения, а CHECK отклоняет значения, нарушающие правило. DEFAULT подставляет значение, если при вставке это поле не указано. Эти проверки помогают не допускать неполных заявок.
Запишите схему и две синтетические строки в SQL-файл. Кавычки вокруг маркера SQL не позволяют оболочке интерпретировать содержимое. SQL-инструкции заканчиваются точкой с запятой. INSERT INTO сопоставляет имена столбцов со значениями в каждой строке:
cat > schema.sql <<'SQL'
CREATE TABLE tickets (
id INTEGER PRIMARY KEY,
subject TEXT NOT NULL CHECK(length(trim(subject)) > 0),
status TEXT NOT NULL DEFAULT 'open' CHECK(status IN ('open','closed')),
source TEXT NOT NULL
);
INSERT INTO tickets (id, subject, status, source) VALUES
(1, 'Cannot sign in', 'open', 'seed'),
(2, 'Invoice copy', 'closed', 'seed');
SQL
Примените файл только к локальной базе данных:
npx wrangler d1 execute DB --local --file schema.sql
При успешном выполнении команда сообщает об исполнении в локальной базе данных. Это не подтверждает наличие таблицы в удалённой базе. Проверьте определения столбцов с помощью PRAGMA table_info в SQLite:
npx wrangler d1 execute DB --local --command "PRAGMA table_info(tickets);"
Ожидаются столбцы id, subject, status и source. Поле pk показывает первичный ключ, а notnull указывает на обязательные значения.
Фильтруйте, изменяйте и удаляйте локальные строки
На этом шаге вы попрактикуетесь с базовыми SQL-командами и оставите маркер, существующий только локально. SELECT выбирает столбцы, FROM указывает таблицу, WHERE фильтрует подходящие строки, а ORDER BY делает порядок строк предсказуемым.
npx wrangler d1 execute DB --local --command "SELECT id, subject FROM tickets WHERE status = 'open' ORDER BY id;"
Результатом должна быть заявка 1 — Cannot sign in. Внутри команды, заключённой в двойные кавычки, SQL-строки используют одинарные кавычки. Добавьте локальную учебную заявку:
npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source) VALUES (3, 'Local rehearsal', 'local');"
UPDATE изменяет подходящие строки. Перед выполнением всегда проверяйте условие WHERE: если его пропустить, изменятся все строки.
npx wrangler d1 execute DB --local --command "UPDATE tickets SET status = 'closed' WHERE id = 3;"
Попробуйте недопустимый статус, чтобы увидеть, как ограничение защищает данные:
npx wrangler d1 execute DB --local --command "UPDATE tickets SET status = 'lost' WHERE id = 3;"
Эта команда намеренно завершается неуспешно. Ожидайте сообщение CHECK constraint failed, а не ошибку аутентификации или сети. Строка останется в состоянии closed. Создайте, а затем удалите временную строку; DELETE удаляет только строки, соответствующие своему предикату:
npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source) VALUES (4, 'Temporary', 'local'); DELETE FROM tickets WHERE id = 4;"
Прочитайте оставшиеся строки:
npx wrangler d1 execute DB --local --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
Ожидаются идентификаторы 1, 2 и 3; заявка 3 должна иметь статус closed и источник local. Заявки 4 нет. Неудачная команда UPDATE не должна была изменить корректную строку.
Заполните и проверьте удалённую базу данных
На этом шаге вы примените ту же схему к облачной базе данных и докажете, что локальные изменения не перенеслись в неё автоматически. Параметр --remote отправляет эти SQL-инструкции в базу данных с UUID выбранной учётной записи.
npx wrangler d1 execute DB --remote --file schema.sql
Если появится запрос, подтвердите только базу данных этой лабораторной работы. Добавьте строку, существующую только в удалённой базе, с тем же идентификатором, что и у локальной учебной строки, но с другими данными:
npx wrangler d1 execute DB --remote --command "INSERT INTO tickets (id, subject, source) VALUES (3, 'Cloud inbox', 'remote');"
Явно прочитайте данные из обоих мест:
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
npx wrangler d1 execute DB --local --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
В удалённой базе заявка 3 имеет значения Cloud inbox, open, remote; в локальной базе заявка 3 по-прежнему имеет значения Local rehearsal, closed, local. Это различие подтверждает, что вы выбрали нужную цель.
В Cloudflare Dashboard выберите ту же учётную запись и откройте Storage & databases → D1 SQLite Database. Найдите точное имя базы данных этого запуска и откройте её страницу сведений. Сравните идентификатор базы данных с указанным в wrangler.jsonc. Если доступно представление таблицы только для чтения, используйте его для просмотра tickets. Не создавайте и не изменяйте записи на этой странице. Содержимое строк подтверждают приведённые выше ответы SQL; задержка в счётчике Metrics этого не подтверждает.
Выполните проверку этого шага до удаления базы данных.

Откройте Explore Data, затем выберите tickets в Studio. Просмотрите строки, не изменяя их. Случайное имя базы на примере относится к одному тестовому запуску; у вас оно будет другим. Заявка 3 — Cloud inbox с источником remote, а в локальной базе по-прежнему находится Local rehearsal с источником local.
Удалите временные ресурсы
На этом шаге вы удалите только ресурсы этой лабораторной работы, пока виртуальная машина ещё авторизована. Сначала завершите все функциональные проверки. Не удаляйте конфигурацию, пока не закончите проверку удаления.
npx wrangler d1 delete DB
Прочитайте запрос и подтвердите, что удаляется только база данных этого запуска. Затем выведите список баз данных:
npx wrangler d1 list --json
В успешном ответе не должны присутствовать записанные вами имя базы данных и UUID. Другие ресурсы могут остаться. Ошибка аутентификации или сети не даёт однозначного результата: восстановите доступ и повторите чтение перед продолжением. Выполните проверку этого шага, пока вы ещё вошли в систему.
Завершите авторизацию этой виртуальной машины
На этом шаге вы завершите авторизацию только после успешной независимой проверки удаления. Выход удаляет сохранённые на этой виртуальной машине данные авторизации Wrangler; одно лишь закрытие виртуальной машины не удаляет облачные ресурсы.
npx wrangler logout
npx wrangler whoami --json
Ожидайте loggedIn: false. Запрос без аутентификации может завершиться с ненулевым кодом; это считается ожидаемым только в том случае, если структурированный ответ явно сообщает, что вы вышли из системы. Завершите проверку, затем закройте окружение лабораторной работы.
Резюме
Вы попрактиковались в создании базы данных заявок службы поддержки. Вы проверили наблюдаемые результаты работы базы данных, явно контролировали выбранную учётную запись и локальное состояние, а затем удалили временные ресурсы перед выходом из системы.



