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 будет использовать конфигурацию вашей БД для генерации локальных типов в соответствии с вашими схемами. Они будут генерироваться каждый раз при запуске сервера разработки, и позволят вам запрашивать и работать с формой ваших данных с безопасностью типов и автозаполнением.
Чтобы поместить данные разработки для тестирования и отладки в ваш проект 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: 'Hope you like Astro DB!' }, { authorId: 2, body: 'Enjoy!'}, ])}
Ваш сервер разработки будет автоматически перезапускать вашу базу данных при каждом изменении этого файла, регенерируя ваши типы и заполняя ваши данные разработки из 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>Comments</h2>
{ comments.map(({ author, body }) => ( <article> <p>Author: {author}</p> <p>{body}</p> </article> ))}
select()
.
Вставка
Заголовок раздела ВставкаЧтобы принимать пользовательский ввод, например, обрабатывать запросы форм и вставлять данные в удаленную базу данных, настройте проект 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">Author</label> <input id="author" name="author" />
<label for="content">Content</label> <textarea id="content" name="content"></textarea>
<button type="submit">Submit</button></form>
<!--выводим `comments`-->
Вы также можете запросить базу данных из конечной точки API. В этом примере удаляется строка из таблицы Comment
по параметру id
:
import type { APIRoute } from "astro";import { db, Comment } from 'astro:db';
export const DELETE: APIRoute = async (ctx) => { await db.delete(Comment).where({ id: ctx.params.id }); return new Response(null, { status: 204 });}
Полный обзор см. в Drizzle API справочник по методу insert()
.
Фильтрация
Заголовок раздела ФильтрацияЧтобы запросить результаты таблицы по определенному свойству, используйте опции 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>Comments</h2>
{ comments.map(({ Author, Comment }) => ( <article> <p>Author: {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: `Test comment ${i}` })); } await db.batch(queries);}
См. документацию по Drizzle db.batch()
для получения дополнительной информации.
Astro Studio
Заголовок раздела Astro StudioAstro DB может подключаться к платформе Astro Studio для быстрого добавления хостинга базы данных в ваш проект. Вы можете просматривать, управлять и развертывать новые хостинговые базы данных из веб-портала Astro Studio.
Создать проект в Astro Studio можно двумя способами:
- с помощью Astro Studio CLI, используя
astro login
для аутентификации иastro link
для создания. - через веб-интерфейс Astro Studio.
Чтобы создать новую базу данных в веб-интерфейсе Astro Studio, нажмите кнопку “create project” в заголовке и следуйте представленным инструкциям. Astro Studio проведет вас через все необходимые шаги, и в конце процесса у вас будет настроенная хостинговая база данных для вашего проекта.
Отправка схем таблиц
Заголовок раздела Отправка схем таблицСхема вашей таблицы будет изменяться со временем по мере роста вашего проекта. Вы можете безопасно тестировать изменения конфигурации локально и отправлять их в вашу базу данных Studio при развертывании.
При создании проекта Studio из панели управления вы сможете создать действие CI GitHub. Это автоматически мигрирует изменения схемы при слиянии с основной веткой вашего репозитория.
Вы также можете отправлять изменения схемы через CLI, используя команду astro db push
:
npm run astro db push
pnpm astro db push
yarn astro db push
Эта команда проверит, можно ли внести изменения без потери данных, и подскажет, какие изменения схемы рекомендуется внести для разрешения конфликтов. Если изменение схемы должно быть выполнено, добавьте флаг --force-reset
, чтобы сбросить все производственные данные.
Отправка данных
Заголовок раздела Отправка данныхВам может потребоваться отправить данные в вашу базу данных 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: 'Palomita', species: 'cat' }, { name: 'Pan', species: 'dog' }, ]);}
Значение, возвращаемое asDrizzleTable('Pets', Pets)
, эквивалентно import { Pets } из 'astro:db'
, но доступно даже тогда, когда генерация типов Astro не может быть запущена.
Вы можете использовать его в любом коде интеграции, который требует запросов или вставок в базу данных.