Знак Taidon: граф состояний над базой данных Документация Taidon Local

Первое знакомство с sqlrs

Разберитесь в состояниях, экземплярах и рецептах, а затем пройдите первый локальный сценарий.

Проверено для sqlrs v0.1.1-rc.6Исходный код 1752abbb
Зачем нужен sqlrs

sqlrs упрощает эксперименты с воспроизводимыми состояниями SQL-базы. Вместо ручной подготовки общей базы вы описываете рецепт, а sqlrs по запросу создаёт из него изолированные рабочие экземпляры для разработки, тестов и проверки миграций.

Из чего состоит sqlrs

Пользователь работает с одной CLI-утилитой sqlrs. Через одинаковые команды она обращается к выбранному варианту продукта. Этот учебник посвящён Local: движок, кэш состояний и рабочие экземпляры находятся на локальной машине и работают от имени текущего пользователя.

Local использует контейнерный runtime — Docker или Podman — чтобы запускать базу и инструменты подготовки. Для начала достаточно понимать четыре объекта:

Рабочая область (workspace)
Каталог проекта с локальной папкой .sqlrs/. Она задаёт границы доступных файлов и хранит настройки подключения к движку.
Рецепт подготовки (prepare-рецепт)
Команда и её входные файлы: SQL-скрипты, подключаемые psql-файлы или Liquibase changelog. Рецепт должен полностью описывать получение нужной базы.
Состояние (state)
Неизменяемый результат выполнения рецепта. sqlrs может сохранить его в кэше и повторно использовать, пока образ, аргументы и входные файлы не изменились.
Экземпляр (instance)
Изменяемая база, созданная из состояния. Тест или приложение меняет свой экземпляр, не затрагивая состояние и другие экземпляры.

Главная идея: храните рецепт, а не готовую базу

Репозиторий хранит миграции, SQL и короткое описание способа их запуска. Готовые состояния остаются локальными производными данными: sqlrs создаёт их по необходимости, переиспользует подходящие результаты и со временем вытесняет невостребованные состояния из ограниченного кэша. Экземпляры также можно создавать и удалять по мере работы. Поэтому инфраструктуру не приходится вручную пополнять отдельной базой для каждого теста или эксперимента.

Первый локальный сценарий

Установите архив Taidon Local для своей платформы, запустите контейнерный runtime и перейдите в каталог учебного проекта. Команда init создаст .sqlrs/config.yaml, выберет доступный способ хранения снимков и запустит локальный движок:

sqlrs init local --snapshot auto
sqlrs status
СоветКогда нужны расширенные параметры init

init также умеет выбирать каталог или образ хранилища, принудительно включать copy, Btrfs или OverlayFS, указывать путь к движку и настраивать Windows через WSL2. Переходите к этим вариантам, только когда автоматический выбор не подходит.

Сокращённый пример sqlrs status
status: ok
endpoint: http://127.0.0.1:…
profile: local
mode: local
workspace: …
container-runtime: ok
cache.stateCount: 0

Значения зависят от машины. Для продолжения важны status: ok, профиль и режим local, найденная рабочая область и готовый контейнерный runtime. Строкиcache.* показывают текущее заполнение локального кэша.

Создайте первое состояние и экземпляр

Начнём с той же подготовки, что используется в короткой проверке установки, но пока ничего не будем запускать поверх базы. Команда выбирает образ postgres:16, выполняет SQL и печатает DSN созданного экземпляра:

sqlrs prepare:psql --image postgres:16 -- -c "create table if not exists smoke_check(id int); insert into smoke_check values (1);"
СоветКак увидеть ход prepare

По умолчанию sqlrs оставляет на экране только самое необходимое. Глобальный флаг -v или --verbose сохраняет промежуточные сообщения и печатает больше деталей: например, sqlrs --verbose prepare:psql ….

Ожидаемый вывод
DSN=postgres://…

Всё после DSN= — строка подключения (connection string) нового экземпляра: адрес, порт, имя базы и учётные данные. Конкретное значение меняется от запуска к запуску; не сохраняйте его в репозитории. Префикс нужен, чтобы shell-скрипт мог отделить значение от имени переменной.

Часть после -- — аргументы psql. sqlrs учитывает команду, образ и входные файлы при идентификации состояния. Само состояние не меняется, а выданный по DSN экземпляр предназначен для изменений.

Посмотрите, что получилось

sqlrs ls --states
sqlrs ls --instances
СоветПолный ID обычно не нужен

Для состояния или экземпляра достаточно однозначного шестнадцатеричного (hex) префикса длиной от восьми символов. В обычных таблицах sqlrs показывает первые 12 символов; флаг --long раскрывает ID полностью. ID фоновой задачи (job), в отличие от них, указывается целиком.

Схема таблицы состояний
STATE_ID      IMAGE_ID               KIND  PREPARE_ARGS  CREATED  SIZE  REFCOUNT
a1b2c3d4e5f6  postgres@0123456789ab  psql  …             …        …     1

STATE_ID идентифицирует неизменяемое состояние, IMAGE_ID — разрешённый образ базы, KIND — способ подготовки, а PREPARE_ARGS — нормализованный рецепт. REFCOUNT показывает, сколько экземпляров ссылаются на состояние. ID, время и размер в примере условные.

Схема таблицы экземпляров
INSTANCE_ID   IMAGE_ID               STATE_ID      NAME  CREATED  EXPIRES  STATUS
f6e5d4c3b2a1  postgres@0123456789ab  a1b2c3d4e5f6        …        …        active

INSTANCE_ID нужен для последующих run и rm. По STATE_ID видно, из какого состояния создан экземпляр; NAME пуст для экземпляра без имени, а STATUS показывает, можно ли им пользоваться.

В первой таблице будет состояние, во второй — созданный на его основе экземпляр. Запустите ту же prepare-команду ещё раз и снова выполните sqlrs ls --instances. Рецепт не изменился, поэтому sqlrs сможет переиспользовать подготовленное состояние, но выдаст новый изменяемый экземпляр. Изменения в одном экземпляре не попадут в другой.

Перенесите настоящий рецепт проекта

Однострочный SQL нужен только для знакомства. Реальные рецепты обычно используют:

  • prepare:psql — SQL-файлы, команды psql и цепочки \i/\ir;
  • prepare:lb — корневой Liquibase changelog и все подключаемые им файлы.

Сначала добейтесь успешного прямого вызова, например sqlrs prepare:psql -- -f db/prepare.sql. Затем сохраните громоздкую команду как репозиторный alias — именованный рецепт, который можно проверять и версионировать вместе с миграциями:

sqlrs alias create test-db prepare:psql -- -f db/prepare.sql
sqlrs prepare test-db
СоветПроверка и список псевдонимов

Проверить корректность псевдонима можно командой sqlrs alias check.

Посмотреть, какие псевдонимы есть в текущей рабочей области, можно командой sqlrs alias ls.

Команда создаст test-db.prep.s9s.yaml. Этот файл нужно коммитить; локальную папку .sqlrs/ — обычно нет. Если вы ещё не знаете, где в проекте находятся подходящие SQL, changelog или настройки, выполните sqlrs discover. Команда только анализирует файлы и предлагает следующие действия: она не создаёт рецепты, не меняет конфигурацию и не запускает миграции.

Выберите время жизни экземпляра

Для короткой SQL-проверки объедините prepare и run в одну команду. После завершения psql sqlrs сразу удалит временный экземпляр:

sqlrs prepare test-db run:psql -- -f tests/db-smoke.sql

Для серии проверок или отладки сначала создайте экземпляр, найдите его id, а затем запускайте команды отдельно. Запущенный отдельно run использует существующий экземпляр и не удаляет его после завершения:

sqlrs prepare test-db
sqlrs ls --instances
sqlrs run:psql --instance INSTANCE_ID -- -f tests/db-smoke.sql

В v0.1.1-rc.6 встроены режимы run для psql и pgbench. Произвольное приложение или обычную систему тестов запускайте привычной командой, передав ей DSN из стандартного вывода prepare через переменную окружения. Подробные примеры для PowerShell и POSIX-совместимой оболочки есть в разделе об автотестах.

Удалите то, что больше не нужно

Экземпляр — изменяемый лист дерева, созданный на основе состояния. У состояния могут быть не только экземпляры, но и дочерние состояния, если один prepare продолжает другой. Без --recurse состояние с любыми потомками заблокировано; с этим флагом sqlrs рассматривает всё поддерево и либо удаляет его целиком, либо не удаляет ничего, если хотя бы один потомок заблокирован.

sqlrs rm INSTANCE_ID_PREFIX
sqlrs rm --recurse STATE_ID_PREFIX
СоветСначала dry-run, затем удаление

Не используйте --recurse и --force без необходимости. Сначала выполните sqlrs rm --dry-run --recurse STATE_ID_PREFIX и проверьте всё дерево. --force разрешает удалить экземпляр с активными подключениями или уже начатую фоновую задачу (job), но сам по себе не включает рекурсивное удаление.

Вывод rm --dry-run --recurse
state a1b2c3d4e5f6 would delete
` instance f6e5d4c3b2a1 would delete (connections=0)

Дерево показывает корневое состояние и всех затронутых потомков. Для экземпляра также выводится число активных подключений. Значение would delete означает, что объект будет удалён при том же вызове без --dry-run; blocked объяснит, что мешает операции.

Различайте два уровня конфигурации

Файл .sqlrs/config.yaml относится к рабочей области: в нём находятся профиль, расположение движка, образ БД и параметры локального запуска. Команда sqlrs configобращается к конфигурации выбранного движка. Например, так можно посмотреть фактически выбранный способ снимков, временно включить copy и затем вернуть автоматический выбор:

sqlrs config get snapshot.backend --effective
sqlrs config set snapshot.backend "copy"
sqlrs config set snapshot.backend "auto"
СоветПроверяйте схему перед config set

Значения для config set задаются в формате JSON и проверяются схемой движка. Перед изменением незнакомого параметра выполните sqlrs config schema и сохраните исходное значение.

Вывод config get --effective
"auto"

Команда печатает эффективное JSON-значение после применения настроек и значений по умолчанию. Поэтому строка заключена в кавычки; числа, boolean, массивы и объекты выводятся в своих JSON-формах.

Куда двигаться дальше

Теперь у вас есть модель sqlrs и первый рабочий цикл. Остальные главы превращают его в повторяемый процесс для реального проекта:

  1. 01

    Подготовьте проект и окружение

    Установите Local, создайте рабочую область и зафиксируйте минимальные настройки проекта.

  2. 02

    Выберите источник состояния

    Превратите SQL-, psql- или Liquibase-сценарий проекта в воспроизводимый рецепт подготовки.

  3. 03

    Проверьте проект командой discovery

    Получите подсказки о структуре проекта и проверьте каждое предложение перед применением.

  4. 04

    Подключите существующие автотесты

    Передайте тестам DSN воспроизводимого экземпляра и сохраните привычный способ запуска.

  5. 05

    Анализируйте миграции между ревизиями

    Сравнивайте файловые входы и поднимайте состояния из коммитов и тегов с учётом ограничений diff.

  6. 06

    Разберите типовые проблемы

    Начните с безопасных проверок рабочей области, окружения, рецептов, кэша и Git-контекста.

Границы учебника

Команды проверены по интерфейсу релиз-кандидата v0.1.1-rc.6. Нативная подготовка покрывает psql и Liquibase. Для Flyway, ORM-миграций и собственного инструмента миграций ниже показан переходный путь через воспроизводимый SQL. Shared остаётся закрытой бетой, Managed — планируемым продуктом; все практические примеры этой версии учебника относятся к Local.

Подготовьте рабочий проект

Проверьте требования своей платформы и создайте рабочую область в корне репозитория.

Перейти к настройке