Введение
Вашему сервису тикетов нужно добавить срочность, не потеряв существующие запросы. Развертывание схемы может завершиться ошибкой, если старые строки не соответствуют новому правилу. Вы создадите упорядоченную миграцию, протестируете её локально и примените тот же файл удалённо, сохранив идентификаторы и темы тикетов.
Эта лабораторная работа начинается независимо от предыдущих: начальная миграция уже предоставлена. Предполагается, что вы знакомы с созданием базы данных и базовым SQL из D01, но предыдущая виртуальная машина или база данных не используются.
Используйте собственную учебную учётную запись и новую виртуальную машину. Сначала настройка установит 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 в браузере, введите текущий код, подтвердите свою учебную учётную запись и разрешения и выполните авторизацию. Дождитесь сообщения терминала об успешном завершении. Никогда не вставляйте пароли или токены в файлы проекта.
npx wrangler whoami --json
Убедитесь, что указано loggedIn: true, затем прочитайте name и id учётной записи, даже если в списке присутствует только одна учётная запись. Скопируйте нужный идентификатор в конфигурацию ниже. Следующая переменная оболочки использует 6 случайных байтов, то есть 12 шестнадцатеричных символов, чтобы избежать совпадений с другими учащимися. Here-document записывает JSON между строками JSON; переменная $RUN раскрывается внутри него.
Обратная косая черта перед $schema сохраняет этот ключ JSON буквально; $RUN по-прежнему подставляет уникальное имя текущего запуска.
RUN=labex-c04-d03-$(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.
Подготовьте существующую базу данных тикетов
На этом шаге вы подготовите существующую версию базы данных приложения. Миграция — это нумерованный SQL-файл, описывающий изменение схемы. Wrangler записывает имена применённых файлов в d1_migrations, поэтому при следующих запусках можно отличить выполненные изменения от ожидающих применения. Настройка предоставляет 0001_initial.sql как старую версию приложения; обновление вы создадите самостоятельно.
Создайте временную облачную базу данных. Параметр --binding DB задаёт короткое имя для кода приложения, --update-config записывает её настоящее имя и UUID в wrangler.jsonc, а --use-remote=false сохраняет разработку локальной:
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
Прочитайте имя и идентификатор созданной базы данных, затем проверьте сохранённую привязку:
cat wrangler.jsonc
Запись DB должна содержать имя базы данных этого запуска. Привязка — это настроенное соединение между кодом и ресурсом. Её UUID идентифицирует облачную базу данных, а параметр --local использует отдельную базу SQLite на этой виртуальной машине. В командах SQL всегда явно указывайте --local или --remote.
Перед применением прочитайте старую схему:
cat migrations/0001_initial.sql
В ней есть два существующих тикета и нет столбца priority. Примените её отдельно к локальной и удалённой базам данных, подтвердив базу данных этой лабораторной работы при появлении запроса:
npx wrangler d1 migrations apply DB --local
npx wrangler d1 migrations apply DB --remote
Проверьте строки и состояние применённых миграций:
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id; SELECT name FROM d1_migrations ORDER BY id;"
Оба исходных тикета должны существовать; применённая миграция — 0001_initial.sql. Применённая миграция становится частью истории: для последующих изменений создавайте новый файл, а не редактируйте эту историю.
Добавьте ограниченный приоритет локально
На этом шаге вы зададите существующим тикетам приоритет по умолчанию, не удаляя таблицу. Команда ALTER TABLE ... ADD COLUMN изменяет таблицу на месте. Для добавленного столбца с ограничением NOT NULL нужно указать полезное значение по умолчанию для старых строк. Ограничение CHECK разрешает только значения normal и urgent.
Создайте следующую нумерованную миграцию:
npx wrangler d1 migrations create DB add_priority
В этом новом проекте команда создаст migrations/0002_add_priority.sql. Проверьте это имя файла в выводе. Запишите изменение в новый файл:
cat > migrations/0002_add_priority.sql <<'SQL'
ALTER TABLE tickets ADD COLUMN priority TEXT NOT NULL DEFAULT 'normal' CHECK(priority IN ('normal','urgent'));
SQL
Выведите список ожидающих миграций, затем примените изменения только локально:
npx wrangler d1 migrations list DB --local
npx wrangler d1 migrations apply DB --local
Оба существующих тикета должны получить значение normal. Добавьте срочный тикет и выполните запрос:
npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source, priority) VALUES (3, 'Service unavailable', 'local', 'urgent'); SELECT id, subject, priority FROM tickets ORDER BY id;"
Приоритет, не входящий в допустимый диапазон, должен вызвать ошибку, а не попасть в таблицу незаметно:
npx wrangler d1 execute DB --local --command "UPDATE tickets SET priority = 'critical' WHERE id = 3;"
Ожидайте ошибку CHECK constraint failed; эта намеренная ошибка оставит у тикета 3 приоритет urgent. Прочитайте PRAGMA table_info(tickets) в удалённой базе данных, чтобы увидеть, что облачная схема всё ещё имеет старую версию:
npx wrangler d1 execute DB --remote --command "PRAGMA table_info(tickets);"
Удалённого столбца priority пока нет. Успешное выполнение миграции локально не изменяет облачную базу данных.
Примените протестированную миграцию удалённо
На этом шаге вы развернёте тот же проверенный файл в удалённой базе данных. Перед подтверждением проверьте ожидающие изменения:
npx wrangler d1 migrations list DB --remote
npx wrangler d1 migrations apply DB --remote
В списке ожидающих должна быть только 0002_add_priority.sql. Существующие строки сохранятся. Добавьте удалённый срочный тикет, затем проверьте данные и историю миграций:
npx wrangler d1 execute DB --remote --command "INSERT INTO tickets (id, subject, source, priority) VALUES (3, 'Service unavailable', 'remote', 'urgent'); SELECT id, subject, priority FROM tickets ORDER BY id; SELECT name FROM d1_migrations ORDER BY id;"
Тикеты 1 и 2 должны сохранить свои темы и получить приоритет normal; у тикета 3 должен быть приоритет urgent. В истории должны быть записаны оба нумерованных файла. Выполните применение ещё раз:
npx wrangler d1 migrations apply DB --remote
Команда должна сообщить, что ожидающих миграций нет, а строки должны остаться без изменений. В этом и состоит смысл таблицы истории: повторный запуск развертывания не выполняет заново уже завершённые файлы. В Dashboard откройте базу данных D1 этого запуска и изучите представление схемы/таблиц, чтобы сопоставить новый столбец с результатом CLI. Не изменяйте схему в Dashboard.

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



