- 起步
- 核心概念
- 教程
- 基础内容
- 内置功能
- 集成
- 操作指南
- 使用指南
- 配置
- 参考
- 社区资源
- 其他
- 为文档做出贡献
- 手动安装 Astro
- 升级到 Astro v4
- 升级到 Astro v3
- 升级到 Astro v2
- Legacy v0.x Upgrade Guide
- 从 Create React App(CRA)迁移
- 关于本教程
- 第一单元:前期准备
- 准备开发环境
- 创建你的第一个 Astro 项目
- 你的第一行 Astro 代码
- 创建在线代码仓库
- 将你的网站部署到网络
- 第二单元:页面
- 创建你的第一个 Astro 页面
- 编写你的第一篇 Markdown 博客文章
- 添加「关于你」的动态内容
- 给你的「关于」页面添加样式
- 应用全局样式
- 第三单元:组件
- 创建一个可重复使用的导航组件
- 创建社交媒体 footer
- 自己动手搭建导航 Header
- 编写你的第一个浏览器脚本
- 第四单元:布局
- 编写你的第一个布局
- 创建并传递数据到博客布局
- 布局结合,两全其美
- 第五单元 - Astro API
- 创建文章存档页
- 生成标签页面
- 编写标签索引页面
- 添加 RSS 订阅源
- 第六单元 - Astro 群岛
- 搭建你的第一个 Astro 岛屿
- 回到干燥的陆地。让你的博客从白天到黑夜,无需岛屿!
- 恭喜你!
- @astrojs/mdx
- 添加阅读时间
- 创建开发者工具栏应用
- @astrojs/alpinejs
- @astrojs/lit
- @astrojs/preact
- @astrojs/react
- @astrojs/solid-js
- @astrojs/svelte
- @astrojs/vue
- @astrojs/cloudflare
- @astrojs/netlify
- @astrojs/node
- @astrojs/vercel
- @astrojs/db
- @astrojs/markdoc
- @astrojs/partytown
- @astrojs/sitemap
- @astrojs/tailwind
- 使用流式处理来提升页面性能
- 从 Gatsby 迁移
- 从 Next.js 迁移
- 从 NuxtJS 迁移
- 从 Docusaurus 迁移到 Astro
- 从 Eleventy 迁移到 Astro
- 从 GitBook 迁移到 Astro
- 从Gridsome迁移到Astro
- 从 Hugo 迁移
- 从 Jekyll 迁移
- 从 Pelican 迁移
- 从 SvelteKit 迁移
- 从VuePress迁移
- 从 WordPress 迁移
- 状态共享
- Storyblok 与 Astro
- Contentful 与 Astro
- ButterCMS & Astro
- Builder.io & Astro
- Cosmic 与 Astro
- DatoCMS 与 Astro
- Front Matter CMS 与 Astro
- Ghost & Astro
- Hashnode & Astro
- Hygraph 与 Astro
- Keystatic & Astro
- Kontent.ai 与 Astro
- 无头模式的 Statamic 与 Astro
- Strapi 与 Astro
- Tina CMS 与 Astro
- Umbraco & Astro
- 无头(headless)模式的 WordPress 与 Astro
- ApostropheCMS 与 Astro
- Caisy & Astro
- CloudCannon与Astro
- Crystallize 与 Astro
- Decap CMS 与 Astro
- Directus 与 Astro
- KeystoneJS 与 Astro
- microCMS & Astro
- Payload CMS 与 Astro
- Prepr CMS & Astro
- Prismic & Astro
- Sanity & Astro
- Sitecore 体验管理器 & Astro
- Spinal & Astro
- 创作内容
- Firebase 与 Astro
- Supabase 与 Astro
- Turso 和 Astro
- Xata 与 Astro
- Appwrite & Astro
- 部署你的 Astro 站点至 Netlify
- 部署你的 Astro 站点至 Vercel
- 如何将你的 Astro 网站部署到 Deno
- 部署你的 Astro 站点至 GitHub Pages
- 部署你的 Astro 站点至 GitLab Pages
- 部署你的 Astro 站点至 Cloudflare Pages
- 将你的 Astro 网站部署到 AWS
- 将你的 Astro 网站通过 Flightcontrol 部署到 AWS
- 将你的 Astro 网站通过 SST 部署到 AWS
- 将你的 Astro 网站部署至 Google Cloud
- 部署你的 Astro 站点至 Google Firebase 托管
- 将你的 Astro 网站部署到 Heroku
- 将你的 Astro 网站部署到 Microsoft Azure
- 部署你的 Astro 站点至 Buddy
- 将你的 Astro 网站部署到 Edgio
- 将你的 Astro 站点部署到 Fly.io
- 将你的 Astro 网站部署到 Render
- 将你的 Astro 网站部署到 Stormkit
- 将你的 Astro 网站部署到 Surge
- 通过 Cleavr 部署你的 Astro 网站
- 将你的 Astro 站点部署到 Kinsta 应用托管
- 将你的 Astro 网站部署到 Space
- 将你的 Astro 站点部署到 Zeabur
- 将你的 Astro 网站部署到 Zerops
- 添加 RSS 摘要
- 安装一个 Vite 或 Rollup 插件
- 构建自定义图像组件
- 使用 API 路由构建表单
- 在 Astro 页面中构建 HTML 表单
- 在 Astro 中使用 Bun
- 调用服务器端点
- 校验验证码
- 用 Docker 来构建你的 Astro 网站
- 动态导入图片
- 为链接添加图标
- 添加 i18n 功能
- 添加最后修改时间
- 在 Astro 组件中共享状态
- 使用 Tailwind Typography 美化渲染后的 Markdown
- Unknown compiler error.
- Astro.redirect is not available in static mode.
- Astro.clientAddress is not available in current adapter.
- Astro.clientAddress cannot be used inside prerendered routes.
- Astro.clientAddress is not available in static mode.
- No static path found for requested path.
- Invalid type returned by Astro page.
- Missing value for client:media directive.
- No matching renderer found.
- No client entrypoint specified in renderer.
- Missing hint on client:only directive.
- Invalid value returned by a getStaticPaths path.
- Invalid entry inside getStaticPath's return value
- Invalid value returned by getStaticPaths.
- getStaticPaths RSS helper is not available anymore.
- Missing params property on getStaticPaths route.
- Invalid value for getStaticPaths route parameter.
- getStaticPaths() function required for dynamic routes.
- Invalid slot name.
- Cannot use Server-side Rendering without an adapter.
- No import found for component.
- Invalid prerender export.
- Invalid component arguments.
- Page number param not found.
- Image missing required "alt" property.
- Error while loading image service.
- Missing image dimensions
- Failed to retrieve remote image dimensions
- Unsupported image format
- Unsupported image conversion
- Prerendered dynamic endpoint has path collision.
- Expected src to be an image.
- Expected image options.
- Cannot set both densities and widths
- Image not found.
- Could not process image metadata.
- Image not found.
- Could not transform image.
- Unable to set response.
- The middleware didn't return a Response.
- The middleware returned something that is not a Response object.
- The endpoint did not return a Response.
- Value assigned to locals is not accepted.
- Astro.response.headers must not be reassigned.
- Can't load the middleware.
- Local images must be imported.
- Astro.glob() used outside of an Astro file.
- Astro.glob() did not match any files.
- A redirect must be given a location with the Location header.
- Invalid dynamic route.
- Could not find Sharp.
- Unknown Vite Error.
- Could not import file.
- Invalid glob pattern.
- Astro couldn't find the correct page to render
- The provided locale does not exist.
- Index page not found.
- You can't use the current function with the current strategy
- Prerendered routes aren't supported when internationalization domains are enabled.
- 启用了手动国际化路由但没有提供中间件。
- Astro can't render the route.
- Unhandled rejection
- i18n Not Enabled
- Route not found.
- Unknown CSS Error
- CSS Syntax Error
- Unknown Markdown Error.
- Failed to parse Markdown frontmatter.
- Invalid frontmatter injection.
- MDX integration missing.
- Unknown configuration error.
- Specified configuration file not found.
- Legacy configuration detected.
- Unknown CLI Error.
- Failed to generate content types.
- Unknown Content Collection Error.
- Content entry frontmatter does not match schema.
- Invalid content entry slug.
- Content Schema should not contain slug.
- Collection does not exist
- Content and data cannot be in same collection.
- Collection contains entries of a different type.
- Data collection entry failed to parse.
- Duplicate content entry slug.
- Actions must be used with server output.
- Unsupported transform in content config.
Astro DB
Astro DB 是一款专为 Astro 设计的全托管 SQL 数据库。你可以在本地开发或者连接到我们 Astro Studio 平台上托管的数据库。
安装
使用 @astrojs/db
集成(v0.8.1
或更高版本)来将 Astro DB 添加到新的或现有的 Astro 项目中(需要 astro@4.5
或更高版本)。Astro 包含一个内置的 astro add
命令能帮你自动化设置此过程。
- npm
- pnpm
- Yarn
npx astro add db
pnpm astro add db
yarn astro add db
如果你愿意,也可以手动安装 @astrojs/db
。
定义你的数据库
Astro DB 是一个用于配置、开发和查询你的数据的完整解决方案。每当你运行 astro dev
时,都会创建一个本地数据库,并使用 LibSQL 来管理你的数据,而无需 Docker 或网络连接。
使用 astro add
命令安装 @astrojs/db
将在你的项目中创建一个 db/config.ts
文件,你将在其中定义你的数据库表:
import { defineDb } from 'astro:db';
export default defineDb({
tables: { },
})
表
Astro DB 中的数据是通过 SQL 表存储的。表将你的数据结构化为行和列,其中列强制每行值的类型。
当你定义一个表时,Astro 将为你的项目生成一个 TypeScript 接口来查询该表。这意味着当你访问数据时,将获得完整的 TypeScript 支持,包括属性自动完成和类型检查。
要配置数据库表,应从 astro:db
导入并使用 defineTable()
和 column
工具。
这个例子配置了一个 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 支持以下列类型:
db/config.tsimport { defineTable, column } from 'astro:db';
const Comment = defineTable({
columns: {
// A string of text.
author: column.text(),
// A whole integer value.
likes: column.number(),
// A true or false value.
flagged: column.boolean(),
// Date/time values queried as JavaScript Date objects.
published: column.date(),
// An untyped JSON object.
metadata: column.json(),
}
});
查看表的列参考以获取更多细节。表引用
表之间的关系是数据库设计中的常见架构。例如,一个 Blog
表可能与 Comment
、Author
和 Category
等其他几个表密切相关。
你可以使用引用列定义来这些表之间的关系并将它们保存到你的数据库中。要建立关系,你需要:
- 在被引用的表上有一个标识符列。这通常是带有
primaryKey
属性的id
列。 - 在基础表上有一个用于存储被引用
id
的列。这将使用references
属性来建立关系。
这个例子显示了一个 Comment
表的 authorId
列引用了 Author
表的 id
列。
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 将使用你的 DB 配置并根据你的架构生成本地类型。这些内容将在每次启动开发服务器时重新生成,并允许你使用类型安全和自动补全来查询和处理你的数据样例。
要为你的 Astro 项目填充开发数据进行测试和调试,你需要创建一个 db/seed.ts
文件。从 astro:db
导入 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
import { db } from 'astro:db';
Astro DB 包含一个内置的 Drizzle ORM 客户端。使用该客户端无需设置或手动配置。当你运行 Astro 时,Astro DB 的 db
客户端会自动配置以与你的数据库(本地或远程)进行通信。它使用你明确的数据库架构定义进行类型安全的 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>
))
}
查看 Drizzle select()
API 参考 以获取完整概述。插入
要接受用户输入,如处理表单请求并将数据插入到你的远程托管数据库,需要为你的 Astro 项目配置 按需渲染 并为你的部署环境 添加一个 SSR 适配器。
这个例子基于解析后表单的 POST 请求向 Comment
表插入一行:
---
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 端点查询你的数据库。这个例子通过 id
参数从 Comment
表中删除一行:
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 });
}
查看 Drizzle insert()
API 参考 以获取完整概述。
过滤
要通过特定属性查询表结果,请使用 Drizzle 的部分查询选项。例如,向你的 select()
查询添加 一个 .where()
调用,并传递你想做的比较操作。
以下例子查询了 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 辅助工具都从 astro:db
模块中暴露出来。这包括:
import { eq, gt, count, sql } from 'astro:db';
关系
你可以使用 SQL 连接从多个表查询关联的数据。要创建一个连接查询,请使用连接操作符扩展你的 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
Studio 功能Astro DB 可以连接到 Astro Studio 平台,快速为你的项目添加一个托管数据库。你可以从 Astro Studio 仪表盘上查看、管理和部署新的托管数据库。
要创建一个新项目,你可以使用现成的模板或访问Astro Studio 指南。
推送表架构
Studio 功能随着你项目的增长,你的表架构也会随着时间的推移而改变。你可以在本地安全地测试配置更改,并在部署时推送到你的 Studio 数据库。
在从仪表板创建 Studio 项目时,你将有创建 GitHub CI 流水线的选项。这将在与你的仓库的主分支合并时自动迁移架构更改。
你也可以通过 CLI 使用 astro db push --remote
命令将本地架构更改推送到 Astro Studio:
- npm
- pnpm
- Yarn
npm run astro db push --remote
pnpm astro db push --remote
yarn astro db push --remote
此命令将验证你的本地更改是否可以在不丢失数据的情况下进行,并在必要时,建议如何安全地修改你的架构以解决冲突。
推送破坏性架构更改
如果你必须以一种与 Astro Studio 托管的现有数据不兼容的方式更改你的表架构,你将需要重置你的生产数据库。
要推送包含破坏性更改的表架构更新,请添加 --force-reset
标志以重置所有生产数据:
- npm
- pnpm
- Yarn
npm run astro db push --remote --force-reset
pnpm astro db push --remote --force-reset
yarn astro db push --remote --force-reset
重命名表
Studio 功能在将你的架构推送到 Astro Studio 之后,可以重命名一个表。
如果你没有任何重要的生产数据,那么你可以使用 --force-reset
标志重置你的数据库。这个标志将会删除数据库中的所有表,并创建新的表,以便它完全匹配你当前的架构。
为了在保留你的生产数据的同时重命名一个表,你必须执行一系列非破坏性更改,以安全地将你的本地架构推送到 Astro Studio。
以下示例将一个表从 Comment
重命名为 Feedback
:
在你的数据库配置文件中,为你想要重命名的表添加
db/config.tsdeprecated: true
属性:const Comment = defineTable({ deprecated: true, columns: { author: column.text(), body: column.text(), } });
添加一个新的表架构(完全匹配现有表的属性)并使用新名称:
db/config.tsconst Comment = defineTable({ deprecated: true, columns: { author: column.text(), body: column.text(), } }); const Feedback = defineTable({ columns: { author: column.text(), body: column.text(), }});
使用
astro db push --remote
推送到 Astro Studio。这将添加新表并将旧表标记为已弃用。更新你的本地项目代码以使用新表而不是旧表。你可能还需要将数据迁移到新表。
当你确信旧表不再被你的项目使用时,可以从你的
db/config.tsconfig.ts
中移除该架构:const Comment = defineTable({ deprecated: true, columns: { author: column.text(), body: column.text(), }}); const Feedback = defineTable({ columns: { author: column.text(), body: column.text(), } });
再次使用
astro db push --remote
命令推送到 Astro Studio。旧表将被删除,只留下新的、重命名的表。
推送数据
Studio 功能你可能需要将数据推送到你的 Studio 数据库进行填充或数据迁移。你可以使用 astro:db
模块创建一个 .ts
文件来编写类型安全的查询。然后,使用命令 astro db execute <file-path> --remote
执行该文件对你的 Studio 数据库:
以下评论可以使用命令 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
Studio 功能默认情况下,当你运行 dev
或 build
命令时,Astro 将使用本地数据库文件。每次运行命令时,表都会从头开始重新创建,并插入开发的样例数据。
要连接到你的托管 Studio 数据库,你可以添加 --remote
参数。使用此参数进行生产部署,以便对你的 Studio 数据库拥有可读写权限。这将允许你 接受并持久化用户数据。
# 使用远程连接进行构建
astro build --remote
# 使用远程连接进行开发
astro dev --remote
要使用远程连接,你需要一个应用令牌来进行 Studio 认证。请访问 Studio 控制面板获取令牌创建和设置指南。
当你准备好部署时,参见我们的 使用 Studio 连接进行部署指南。
构建 Astro DB 集成
Astro 集成 可以通过额外的 Astro DB 表和填充数据来扩展用户项目。
在 astro:db:setup
钩子中使用 extendDb()
方法注册额外的 Astro DB 配置和填充文件。 defineDbIntegration()
辅助函数为 astro:db:setup
钩子提供 TypeScript 支持和自动补全。
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', }); },
// 其他集成钩子...
},
});
}
集成的 配置 和 填充 文件遵循与其用户定义的等效项相同的格式。
在集成中进行类型安全操作
在进行集成工作时,你可能无法从 astro:db
导出的 Astro 生成的表类型中获益。 为了完全的类型安全,使用 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 } from 'astro:db'
,但即使 Astro 的类型生成无法运行时也可用。 你可以在任何需要查询或插入数据库的集成代码中使用它。
自托管生产部署
如果你将网站部署到自管理的主机上,例如 虚拟私人服务器,你可以选择使用数据库文件,而不是连接到 Astro Studio 托管的数据库。
如果你能够接受这些风险,并且能够自己管理部署,你可以使用数据库文件,而不是连接到 Studio。
在构建过程中,设置 ASTRO_DATABASE_FILE
环境变量,将其指向宿主环境中你的 .db
文件的路径:
ASTRO_DATABASE_FILE=/srv/files/database.db astro build
构建过程会将此路径静态编译为你的生产数据库。当你部署并启动你的服务器时,它将连接到生产主机上此路径的文件。
此外,推送任何表架构更改(也称为“架构迁移”)必须使用此环境变量手动管理。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论