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 db
pnpm astro add db
yarn 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 push
pnpm astro db push
yarn astro db push
Эта команда проверит, можно ли внести изменения без потери данных, и подскажет, какие изменения схемы рекомендуется внести для разрешения конфликтов. Если изменение схемы должно быть выполнено, добавьте флаг --force-reset
, чтобы сбросить все производственные данные.
Внесение критических изменений в схему
Заголовок раздела Внесение критических изменений в схемуЭто уничтожит вашу базу данных. Выполняйте эту команду только в том случае, если вам не нужны производственные данные.
Если вам необходимо изменить схему таблиц таким образом, чтобы она была несовместима с существующими данными, размещёнными в Astro Studio, вам придется перезагрузить свою производственную базу данных.
Чтобы отправить обновление схемы таблицы, содержащее разрушающее изменение, добавьте флаг --force-reset
, чтобы сбросить все производственные данные:
npm run astro db push --remote --force-reset
pnpm astro db push --remote --force-reset
yarn 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 не может быть запущена.
Вы можете использовать его в любом коде интеграции, который требует запросов или вставок в базу данных.