Astro DB
Astro DB — это полностью управляемая база данных SQL, специально разработанная для Astro. Разрабатывайте локально или подключайтесь к хостингу базы данных, управляемой на нашей платформе Astro Studio.
Установка
Заголовок раздела УстановкаДобавьте Astro DB в новый или существующий проект Astro (требуется astro@4.5 или более поздняя версия) с помощью интеграции @astrojs/db (v0.8.1 или более поздняя версия). Astro включает встроенную команду astro add для автоматизации процесса установки.
npx astro add dbpnpm astro add dbyarn astro add dbПри желании вы можете установить @astrojs/db вручную.
Определение вашей базы данных
Заголовок раздела Определение вашей базы данныхAstro DB — это комплексное решение для конфигурирования, разработки и запроса ваших данных. Локальная база данных создается каждый раз, когда вы запускаете astro dev, используя LibSQL для управления вашими данными без необходимости использования Docker или сетевого подключения.
Установка @astrojs/db с помощью команды astro add создаст в вашем проекте файл db/config.ts, в котором вы определите таблицы вашей базы данных:
import { defineDb } from 'astro:db';
export default defineDb({ tables: { },})Таблицы
Заголовок раздела ТаблицыДанные в Astro DB хранятся с помощью таблиц SQL. Таблицы структурируют данные в строки и столбцы, где столбцы определяют тип значения каждой строки.
Когда вы определяете таблицу, Astro генерирует интерфейс TypeScript для запроса этой таблицы из вашего проекта. В результате вы получаете полную поддержку TypeScript при доступе к данным с автозаполнением свойств и проверкой типов.
Чтобы сконфигурировать таблицу базы данных, импортируйте и используйте утилиты defineTable() и column из astro:db.
В этом примере настраивается таблица Comment с необходимыми текстовыми колонками для author и body. Затем сделайте ее доступной для вашего проекта с помощью экспорта defineDb().
import { defineDb, defineTable, column } from 'astro:db';
const Comment = defineTable({ columns: { author: column.text(), body: column.text(), }})
export default defineDb({ tables: { Comment },})Столбцы
Заголовок раздела СтолбцыДанные в Astro DB хранятся с использованием таблиц SQL. Таблицы структурируют ваши данные в строки и столбцы, где столбцы определяют тип значения каждой строки. Astro DB поддерживает следующие типы столбцов:
import { defineTable, column } from 'astro:db';
const Comment = defineTable({ columns: { // Строка текста. author: column.text(), // Целочисленное значение. likes: column.number(), // Значение true или false. flagged: column.boolean(), // Значения даты/времени запрашиваются как объекты JavaScript Date. published: column.date(), // Нетипизированный JSON объект. metadata: column.json(), }});Ссылки на таблицы
Заголовок раздела Ссылки на таблицыОтношения между таблицами являются распространенным шаблоном при проектировании баз данных. Например, таблица Blog может быть тесно связана с другими таблицами Comment, Author и Category.
Вы можете определить эти отношения между таблицами и сохранить их в схеме базы данных с помощью столбцов ссылок. Чтобы установить отношения, вам понадобятся:
- Столбец идентификатора в целевой таблице. Обычно это столбец
idсо свойствомprimaryKey. - Столбец в базовой таблице для хранения ссылающегося
id. Для этого используется свойствоreferences, устанавливающее связь.
В этом примере столбец Comment таблицы authorId ссылается на столбец id таблицы Author.
const Author = defineTable({ columns: { id: column.number({ primaryKey: true }), name: column.text(), }});
const Comment = defineTable({ columns: { authorId: column.number({ references: () => Author.columns.id }), content: column.text(), }});Заполнение вашей базы данных
Заголовок раздела Заполнение вашей базы данныхВ процессе разработки Astro будет использовать конфигурацию вашей БД для создания локальных типов в соответствии с вашими схемами. Они будут генерироваться каждый раз при запуске dev-сервера и позволят вам запрашивать и работать с формой ваших данных с безопасностью типов и автозаполнением.
Чтобы поместить данные разработки для тестирования и отладки в ваш проект Astro, создайте файл db/seed.ts. Импортируйте объект db и любую сконфигурированную таблицу из astro:db. Используйте функцию db.insert() для создания массива объектов данных строк таблицы.
Следующий пример определяет две строки данных разработки для таблицы Comment:
import { db, Comment } from 'astro:db';
export default async function() { await db.insert(Comment).values([ { authorId: 1, body: 'Надеюсь, вам понравится Astro DB!' }, { authorId: 2, body: 'Наслаждайтесь!'}, ])}Ваш сервер разработки будет автоматически перезапускать вашу базу данных при каждом изменении этого файла, регенерируя ваши типы и заполняя ваши данные разработки из seed.ts.
Запрос к базе данных
Заголовок раздела Запрос к базе данныхВы можете запросить вашу базу данных с любой страницы Astro или конечной точки в вашем проекте, используя предоставленные db ORM и конструктор запросов.
Drizzle ORM
Заголовок раздела Drizzle ORMimport { db } from 'astro:db';Astro DB включает встроенный клиент Drizzle ORM. Для использования клиента не требуется установка или ручная настройка. Клиент Astro DB db автоматически настраивается на взаимодействие с вашей базой данных (локальной или удалённой), когда вы запускаете Astro. Он использует вашу точную конфигурацию схемы базы данных для безопасных типизированных SQL запросов с ошибками TypeScript, если вы ссылаетесь на несуществующий столбец или таблицу.
Выборка
Заголовок раздела ВыборкаСледующий пример выбирает все строки таблицы Comment. Это возвращает полный массив заполненных данных разработки из db/seed.ts, который затем можно использовать в шаблоне страницы:
---import { db, Comment } from 'astro:db';
const comments = await db.select().from(Comment);---
<h2>Комментарии</h2>
{ comments.map(({ author, body }) => ( <article> <p>Автор: {author}</p> <p>{body}</p> </article> ))}select() - Drizzle ORM.
Вставка
Заголовок раздела ВставкаЧтобы принимать пользовательский ввод, например, обрабатывать запросы форм и вставлять данные в удалённую базу данных, настройте проект Astro на рендеринг по запросу и добавьте адаптер SSR для вашей среды развёртывания.
В этом примере вставляется строка в таблицу Comment на основе обработанного запроса формы POST:
---import { db, Comment } from 'astro:db';
if (Astro.request.method === 'POST') { // парсинг данных формы const formData = await Astro.request.formData(); const author = formData.get('author'); const content = formData.get('content'); if (typeof author === 'string' && typeof content === 'string') { // вставляем данные формы в таблицу Comment await db.insert(Comment).values({ author, content }); }}
// выводим новый список комментариев при каждом запросеconst comments = await db.select().from(Comment);---
<form method="POST" style="display: grid"> <label for="author">Автор</label> <input id="author" name="author" />
<label for="content">Контент</label> <textarea id="content" name="content"></textarea>
<button type="submit">Отправить</button></form>
<!--выводим `comments`-->Вы также можете запросить базу данных из конечной точки API. В этом примере удаляется строка из таблицы Comment по параметру id:
import type { APIRoute } from "astro";import { db, Comment, eq } from 'astro:db';
export const DELETE: APIRoute = async (ctx) => { await db.delete(Comment).where(eq(Comment.id, ctx.params.id )); return new Response(null, { status: 204 });}Полный обзор см. в справочнике по методу insert() - Drizzle ORM.
Фильтрация
Заголовок раздела ФильтрацияЧтобы запросить результаты таблицы по определённому свойству, используйте опции Drizzle для частичных выборок. Например, добавьте вызов .where() к вашему запросу select() и передайте сравнение, которое вы хотите сделать.
Следующий пример запрашивает все строки в таблице Comment, содержащие фразу «Astro DB». Используйте оператор like(), чтобы проверить, присутствует ли фраза внутри body:
---import { db, Comment, like } from 'astro:db';
const comments = await db.select().from(Comment).where( like(Comment.body, '%Astro DB%'));---Утилиты Drizzle
Заголовок раздела Утилиты DrizzleВсе утилиты Drizzle для создания запросов доступны из модуля astro:db. Среди них:
- Операторы фильтрации типа
eq()иgt() - Вспомогательные функции агрегации типа
count() - Вспомогательный метод
sqlдля написания необработанных SQL-запросов
import { eq, gt, count, sql } from 'astro:db';Отношения
Заголовок раздела ОтношенияВы можете запрашивать связанные данные из нескольких таблиц с помощью SQL-запроса join. Чтобы создать запрос с объединением, расширьте оператор db.select() оператором объединения. Каждая функция принимает таблицу для объединения и условие для сопоставления строк между двумя таблицами.
В этом примере используется функция innerJoin() для объединения авторов Comment с их связанной информацией Author на основе столбца authorId. В результате возвращается массив объектов с каждой строкой Author и Comment в качестве свойств верхнего уровня:
---import { db, eq, Comment, Author } from 'astro:db';
const comments = await db.select() .from(Comment) .innerJoin(Author, eq(Comment.authorId, Author.id));---
<h2>Комментарии</h2>
{ comments.map(({ Author, Comment }) => ( <article> <p>Автор: {Author.name}</p> <p>{Comment.body}</p> </article> ))}См. Справочник по соединениям Drizzle для всех доступных операторов соединения и параметров конфигурации.
Пакетные транзакции
Заголовок раздела Пакетные транзакцииВсе удалённые запросы к базе данных выполняются как сетевой запрос. При выполнении большого количества запросов может потребоваться объединить их в одну транзакцию или обеспечить автоматический откат в случае неудачи какого-либо запроса.
В этом примере несколько строк обрабатываются одним запросом с помощью метода db.batch():
import { db, Author, Comment } from 'astro:db';
export default async function () { const queries = []; // Добавить 100 тестовых комментариев в вашу удалённую базу данных // одним сетевым запросом. for (let i = 0; i < 100; i++) { queries.push(db.insert(Comment).values({ body: `Тестовый комментарий ${i}` })); } await db.batch(queries);}См. документацию по Drizzle db.batch() для получения дополнительной информации.
Astro Studio
Заголовок раздела Astro StudioAstro DB может подключаться к платформе Astro Studio, чтобы быстро добавить хостинг базы данных в ваш проект. Вы можете просматривать, управлять и развёртывать новые хостинговые базы данных прямо из панели управления Astro Studio.
Веб-портал Astro Studio позволяет вам подключаться и управлять вашими удаленными базами данных Astro DB через веб-интерфейс или с использованием CLI-команд.
Из вашей панели управления Studio у вас есть доступ к управлению учетной записью, справочным статьям и консоли сообщений поддержки.
Посетите Astro Studio, чтобы зарегистрироваться или войти в систему.
Создание нового проекта Studio
Заголовок раздела Создание нового проекта StudioСуществует два способа создания проекта в Astro Studio:
-
Использовать веб-интерфейс Astro Studio для создания из нового или существующего репозитория GitHub.
Чтобы начать, нажмите кнопку “create project” в заголовке и следуйте инструкциям. Astro Studio подключится к вашему репозиторию GitHub и создаст новую хостинговую базу данных для вашего проекта.
-
Использовать Astro Studio CLI для создания из любого локального проекта Astro. Для начала можно выполнить следующие команды:
Окно терминала # Войдите в Astro Studio с помощью вашей учетной записи GitHubnpx astro login# Свяжите новый проект, следуя инструкциямnpx astro link# (Необязательно) Отправьте вашу локальную конфигурацию базы данных на удаленную базу данныхnpx astro db pushОкно терминала # Войдите в Astro Studio с помощью вашей учетной записи GitHubpnpm astro login# Свяжите новый проект, следуя инструкциямpnpm astro link# (Необязательно) Отправьте вашу локальную конфигурацию базы данных на удаленную базу данныхpnpm astro db pushОкно терминала # Log in to Astro Studio with your GitHub accountyarn astro login# Свяжите новый проект, следуя инструкциямyarn astro link# (Необязательно) Отправьте вашу локальную конфигурацию базы данных на удаленную базу данныхyarn astro db pushПосле того как вы вошли в систему и успешно подключились, вы можете выполнять все команды Astro DB для управления удаленной базой данных.
О всех доступных командах см. в справочнике Astro DB CLI.
Развёртывание с подключением к Studio
Заголовок раздела Развёртывание с подключением к StudioВы можете развернуть свой проект Astro DB с живым подключением к вашей базе данных Studio. Это возможно на любой платформе развёртывания с использованием статических сборок или адаптера SSR.
Сначала настройте свою команду сборки для подключения к Studio с использованием флага --remote. В этом примере флаг применяется к скрипту "build" в файле package.json вашего проекта. Если ваша платформа развёртывания принимает команду сборки, убедитесь, что она установлена на npm run build.
{ "scripts": { "build": "astro build --remote" }}Создание токена приложения Studio
Заголовок раздела Создание токена приложения StudioДля доступа к вашей базе данных Studio из продакшн-развёртывания вам нужно создать токен приложения. Вы можете создать токен приложения на панели управления вашего проекта Studio, перейдя на вкладку Settings и выбрав Tokens.
Скопируйте сгенерированный токен и примените его в качестве переменной окружения / секрета окружения на вашей платформе развёртывания, используя имя ASTRO_STUDIO_APP_TOKEN.
Настройте действие GitHub CI
Заголовок раздела Настройте действие GitHub CIВы можете автоматически отправлять изменения схемы в вашу базу данных Studio с использованием действия Studio CI. Это позволит убедиться, что изменения могут быть внесены безопасно, и поддерживать конфигурацию в актуальном состоянии при каждом слиянии с main.
Следуйте документации GitHub, чтобы настроить новый секрет в вашем репозитории с именем ASTRO_STUDIO_APP_TOKEN и вашим токеном приложения Studio в качестве значения секрета.
После того как секрет настроен, создайте новый файл рабочего процесса GitHub Actions в директории проекта .github/workflows для проверки репозитория и установки Node.js в качестве шагов, а также используйте действие withastro/action-studio для синхронизации изменений схемы.
После настройки секрета создайте новый файл рабочего процесса GitHub Actions в директории проекта .github/workflows для проверки репозитория и установки Node.js в качестве шагов, а также используйте действие withastro/action-studio для синхронизации изменений схемы.
Действие запустит astro db verify на всех событиях-триггерах, чтобы убедиться, что изменения схемы могут быть применены безопасно. Если вы специально добавите триггер push, действие перенесет эти изменения в базу данных Studio.
Приведенный пример GitHub Action _studio.yml отправляет изменения при каждом обновлении ветки main:
name: Astro Studio
env: ASTRO_STUDIO_APP_TOKEN: ${{secrets.ASTRO_STUDIO_APP_TOKEN }}
on: push: branches: - main pull_request: types: [opened, reopened, synchronize]
jobs: DB: permissions: contents: read actions: read pull-requests: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - uses: jaid/action-npm-install@v1.2.1 - uses: withastro/action-studio@mainОтправка схем таблиц
Заголовок раздела Отправка схем таблицСхема вашей таблицы будет изменяться со временем по мере роста вашего проекта. Вы можете безопасно тестировать изменения конфигурации локально и отправлять их в вашу базу данных Studio при развёртывании.
При создании проекта Studio из панели управления вы сможете создать действие CI GitHub. Это автоматически мигрирует изменения схемы при слиянии с основной веткой вашего репозитория.
Вы также можете отправлять изменения схемы через CLI, используя команду astro db push:
npm run astro db pushpnpm astro db pushyarn astro db pushЭта команда проверит, можно ли внести изменения без потери данных, и подскажет, какие изменения схемы рекомендуется внести для разрешения конфликтов. Если изменение схемы должно быть выполнено, добавьте флаг --force-reset, чтобы сбросить все производственные данные.
Внесение критических изменений в схему
Заголовок раздела Внесение критических изменений в схемуЭто уничтожит вашу базу данных. Выполняйте эту команду только в том случае, если вам не нужны производственные данные.
Если вам необходимо изменить схему таблиц таким образом, чтобы она была несовместима с существующими данными, размещёнными в Astro Studio, вам придется перезагрузить свою производственную базу данных.
Чтобы отправить обновление схемы таблицы, содержащее разрушающее изменение, добавьте флаг --force-reset, чтобы сбросить все производственные данные:
npm run astro db push --remote --force-resetpnpm astro db push --remote --force-resetyarn astro db push --remote --force-resetПереименование таблиц
Заголовок раздела Переименование таблицМожно переименовать таблицу после загрузки схемы в Astro Studio.
Если у вас нет важных производственных данных, то вы можете сбросить базу данных, используя флаг --force-reset. Этот флаг сбросит все таблицы в базе данных и создаст новые, чтобы они точно соответствовали вашей текущей схеме.
Чтобы переименовать таблицу, сохранив при этом производственные данные, необходимо выполнить ряд необратимых изменений, чтобы безопасно перенести локальную схему в студию Astro.
В следующем примере таблица переименована из Comment в Feedback:
-
В файле конфигурации базы данных добавьте свойство
deprecated: trueдля таблицы, которую вы хотите переименовать:db/config.ts const Comment = defineTable({deprecated: true,columns: {author: column.text(),body: column.text(),}}); -
Добавьте новую схему таблицы (точно соответствующую свойствам существующей таблицы) с новым именем:
db/config.ts const Comment = defineTable({deprecated: true,columns: {author: column.text(),body: column.text(),}});const Feedback = defineTable({columns: {author: column.text(),body: column.text(),}}); -
Отправьте изменения в Astro Studio с помощью команды
astro db push --remote. Это добавит новую таблицу и пометит старую как устаревшую. -
Обновите любой локальный код проекта, чтобы использовать новую таблицу вместо старой. Возможно, вам также потребуется перенести данные в новую таблицу.
-
Когда вы убедитесь, что старая таблица больше не используется в вашем проекте, вы можете удалить схему из вашего
config.ts:db/config.ts const Comment = defineTable({deprecated: true,columns: {author: column.text(),body: column.text(),}});const Feedback = defineTable({columns: {author: column.text(),body: column.text(),}}); -
Снова перейдите в Astro Studio с помощью
astro db push --remote. Старая таблица будет удалена, останется только новая, переименованная таблица.
Отправка данных
Заголовок раздела Отправка данныхВам может потребоваться отправить данные в вашу базу данных Studio для заполнения или миграции данных. Вы можете создать файл .ts с помощью модуля astro:db для написания типобезопасных запросов. Затем выполните этот файл в базе данных Studio с помощью команды astro db execute <file-path> --remote:
Следующие комментарии могут быть добавлены с использованием команды astro db execute db/seed.ts --remote:
import { Comment } from 'astro:db';
export default async function () { await db.insert(Comment).values([ { authorId: 1, body: 'Hope you like Astro DB!' }, { authorId: 2, body: 'Enjoy!' }, ])}См. Справочник по CLI для ознакомления с полным списком команд.
Подключение к Astro Studio
Заголовок раздела Подключение к Astro StudioПо умолчанию Astro использует локальный файл базы данных при выполнении команд dev или build. Таблицы создаются с нуля при выполнении каждой команды, и в них вставляются исходные данные для разработки.
Чтобы подключиться к вашей хостинговой базе данных Studio, вы можете добавить флаг --remote. Используйте этот флаг для развёртывания на производство с возможностью чтения и записи в вашу базу данных Studio. Это позволит вам принимать и сохранять данные пользователей.
# Сборка с удалённым подключениемastro build --remote
# Разработка с удалённым подключениемastro dev --remoteБудьте осторожны, используя --remote в разработке. Это приведет к подключению к живой продакшн-базе данных, и все вставки, обновления или удаления будут сохранены.
Чтобы использовать удалённое подключение, вам понадобится токен приложения для аутентификации в Studio. Инструкции по созданию и настройке токена можно найти на приборной панели Studio.
Когда вы будете готовы к развёртыванию, ознакомьтесь с нашим Руководством по развёртыванию с подключением к Studio.
Создание интеграций Astro DB
Заголовок раздела Создание интеграций Astro DBИнтеграции Astro позволяют расширить пользовательские проекты дополнительными таблицами и данными для заполнения Astro DB.
Используйте метод extendDb() в хуке astro:db:setup для регистрации дополнительных конфигурационных файлов Astro DB и файлов данных для заполнения.
Вспомогательная функция defineDbIntegration() обеспечивает поддержку TypeScript и автозаполнение для хука astro:db:setup.
import { defineDbIntegration } from '@astrojs/db/utils';
export default function MyIntegration() { return defineDbIntegration({ name: 'my-astro-db-powered-integration', hooks: { 'astro:db:setup': ({ extendDb }) => { extendDb({ configEntrypoint: '@astronaut/my-package/config', seedEntrypoint: '@astronaut/my-package/seed', }); }, // Другие интеграционные хуки... }, });}Файлы конфигурации config и seed для интеграции следуют тому же формату, что и их пользовательские аналоги.
Типобезопасные операции в интеграциях
Заголовок раздела Типобезопасные операции в интеграцияхПри работе над интеграциями вы можете не воспользоваться сгенерированными Astro типами таблиц, экспортированными из astro:db.
Для обеспечения полной безопасности типов используйте утилиту asDrizzleTable() для создания объекта-ссылки на таблицу, который можно использовать для операций с базой данных.
Например, в интеграции задана следующая таблица базы данных Pets:
import { defineDb, defineTable, column } from 'astro:db';
export const Pets = defineTable({ columns: { name: column.text(), species: column.text(), },});
export default defineDb({ tables: { Pets } });Файл данных может импортировать Pets и использовать asDrizzleTable() для вставки строк в вашу таблицу с проверкой типов:
import { asDrizzleTable } from '@astrojs/db/utils';import { db } from 'astro:db';import { Pets } from './config';
export default async function() { const typeSafePets = asDrizzleTable('Pets', Pets);
await db.insert(typeSafePets).values([ { name: 'Мурка', species: 'кошка' }, { name: 'Бублик', species: 'собака' }, ]);}Значение, возвращаемое asDrizzleTable('Pets', Pets), эквивалентно import { Pets } из 'astro:db', но доступно даже тогда, когда генерация типов Astro не может быть запущена.
Вы можете использовать его в любом коде интеграции, который требует запросов или вставок в базу данных.