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 не может быть запущена.
Вы можете использовать его в любом коде интеграции, который требует запросов или вставок в базу данных.