Skip to content

Database

By default, we use Drizzle as our database layer to handle schema, migrations, etc.

We’ve also chosen to go with Neon.

You can use any PostgreSQL database or migrate to any other database provider.

You can find the current schema file in src/db/schema.ts, you can add new tables or modify existing tables easily following this guide from Drizzle.

Once you’ve made changes you can follow these steps to generate migrations and apply them:

  1. Generate database migrations

    Terminal window
    pnpm run db:generate
  2. Run database migration

    Terminal window
    pnpm run db:migrate

To query data, you can use Drizzle, for example using our included notes sample app to query notes for a user:

src/pages/notes/list.astro
//...
const session = Astro.locals.session;
const userId = session.get("userId"); // Get the session data
import { db } from "@/db";
import { notes } from "@/db/schema";
import { eql } from "drizzle-orm";
//...
let myNotes = await db
.select()
.from(notes)
.where(eq(notes.userId, user.id))
.execute();
//...

This tells the app to query notes belonging to the logged in user and return them, since we’re using the notes schema it will follow what we’ve set as fields.

Saving new data is easy, using our example notes again:

src/pages/notes/actions.astro
//...
const session = Astro.locals.session;
const userId = session.get("userId"); // Get the session data
import { db } from "@/db";
import { notes } from "@/db/schema";
import { eql } from "drizzle-orm";
//...
await db.insert(notes).values({ title, content, userId: userId });
//...

Similarly, updating data is just as easy:

src/pages/notes/actions.astro
//...
const session = Astro.locals.session;
const userId = session.get("userId"); // Get the session data
import { db } from "@/db";
import { notes } from "@/db/schema";
import { eql } from "drizzle-orm";
//...
await db.update(notes).set({ title, content, updatedAt: new Date() }).where(
and(
eq(notes.id, id),
eq(notes.userId, userId)
)
);
//...

This tells it to update the title, content and the updateAt fields for the note that matches id and belongs to the user as denoted by userId.

Finally, to delete data:

src/pages/notes/actions.astro
//...
const session = Astro.locals.session;
const userId = session.get("userId"); // Get the session data
import { db } from "@/db";
import { notes } from "@/db/schema";
import { eql } from "drizzle-orm";
//...
await db.delete(notes).where(
and(
eq(notes.id, id),
eq(notes.userId, userId)
)
);
//...

This tells it to delete the note that matches id and belongs to the user as denoted by userId.

Drizzle brings an extensive ORM to our starter that lets you do a number of things without too much code, so I recommend diving into it and learning what you can do, we’ve kept what we do with Drizzle mostly simple to get started.