Skip to content

Commit 76fa3f5

Browse files
author
beerose
committed
Add quick drizzle guide
1 parent 00b551b commit 76fa3f5

File tree

3 files changed

+283
-0
lines changed

3 files changed

+283
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.. edb:env-switcher::
2+
3+
==================
4+
Adding Drizzle ORM
5+
==================
6+
7+
.. toctree::
8+
:maxdepth: 1
9+
:hidden:
10+
11+
nextjs
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
.. _ref_guide_gel_drizzle:
2+
3+
======================
4+
Drizzle ORM in Next.js
5+
======================
6+
7+
|Gel| integrates seamlessly with Drizzle ORM, providing a type-safe and intuitive way to interact with your database in TypeScript applications.
8+
9+
Enable Drizzle in your Gel project
10+
==================================
11+
12+
.. edb:split-section::
13+
14+
To integrate Drizzle with your Gel project, you'll need to install the necessary dependencies:
15+
16+
.. code-block:: bash
17+
18+
$ npm install drizzle-orm
19+
$ npm install -D drizzle-kit
20+
21+
22+
.. edb:split-section::
23+
24+
Next, create a Drizzle configuration file in your project root to tell Drizzle how to work with your Gel database:
25+
26+
.. code-block:: typescript
27+
:caption: drizzle.config.ts
28+
29+
import { defineConfig } from 'drizzle-kit';
30+
31+
export default defineConfig({
32+
dialect: 'gel',
33+
});
34+
35+
36+
Sync your Gel schema with Drizzle
37+
=================================
38+
39+
.. edb:split-section::
40+
41+
Before using Drizzle with your Gel database, you'll need to let Drizzle introspect your schema. This step generates TypeScript files that Drizzle can use to interact with your database.
42+
43+
.. code-block:: bash
44+
45+
$ npx drizzle-kit pull
46+
47+
48+
.. edb:split-section::
49+
50+
This command will create a schema file based on your Gel database. The file will typically look something like this:
51+
52+
.. code-block:: typescript
53+
:caption: drizzle/schema.ts
54+
:class: collapsible
55+
56+
import { gelTable, uniqueIndex, uuid, smallint, text, timestamp, relations } from "drizzle-orm/gel-core"
57+
import { sql } from "drizzle-orm"
58+
59+
export const books = gelTable("Book", {
60+
id: uuid().default(sql`uuid_generate_v4()`).primaryKey().notNull(),
61+
title: text().notNull(),
62+
author: text(),
63+
year: smallint(),
64+
genre: text(),
65+
read_date: timestamp(),
66+
}, (table) => [
67+
uniqueIndex("books_pkey").using("btree", table.id.asc().nullsLast().op("uuid_ops")),
68+
]);
69+
70+
export const notes = gelTable("Note", {
71+
id: uuid().default(sql`uuid_generate_v4()`).primaryKey().notNull(),
72+
text: text().notNull(),
73+
created_at: timestamp().default(sql`datetime_current()`),
74+
book_id: uuid().notNull(),
75+
}, (table) => [
76+
uniqueIndex("notes_pkey").using("btree", table.id.asc().nullsLast().op("uuid_ops")),
77+
]);
78+
79+
80+
Keep Drizzle in sync with Gel
81+
=============================
82+
83+
.. edb:split-section::
84+
85+
To keep your Drizzle schema in sync with your Gel schema, add a hook to your ``gel.toml`` file. This hook will automatically run ``drizzle-kit pull`` after each migration:
86+
87+
.. code-block:: toml
88+
:caption: gel.toml
89+
90+
[hooks]
91+
after_migration_apply = [
92+
"npx drizzle-kit pull"
93+
]
94+
95+
96+
97+
With this hook in place, your Drizzle schema will automatically update whenever you apply Gel migrations.
98+
99+
100+
Create a database client
101+
========================
102+
103+
.. edb:split-section::
104+
105+
Now, let's create a database client that you can use throughout your application:
106+
107+
.. code-block:: typescript
108+
:caption: src/db/index.ts
109+
110+
import { drizzle } from 'drizzle-orm/gel';
111+
import { createClient } from 'gel-js';
112+
import * as schema from '@/drizzle/schema';
113+
import * as relations from '@/drizzle/relations';
114+
115+
// Import our schema
116+
import * as schema from './schema';
117+
118+
// Initialize Gel client
119+
const gelClient = createClient();
120+
121+
// Create Drizzle instance
122+
export const db = drizzle({
123+
client: gelClient, schema: {
124+
...schema,
125+
...relations
126+
},
127+
});
128+
129+
// Helper types for use in our application
130+
export type Book = typeof schema.book.$inferSelect;
131+
export type NewBook = typeof schema.book.$inferInsert;
132+
133+
export type Note = typeof schema.note.$inferSelect;
134+
export type NewNote = typeof schema.note.$inferInsert;
135+
136+
137+
Perform database operations with Drizzle
138+
========================================
139+
140+
.. edb:split-section::
141+
142+
Drizzle provides a clean, type-safe API for database operations. Here are some examples of common operations:
143+
144+
**Selecting data:**
145+
146+
.. code-block:: typescript
147+
148+
// Get all books with their notes
149+
const allBooks = await db.query.book.findMany({
150+
with: {
151+
notes: true,
152+
},
153+
});
154+
155+
// Get a specific book
156+
const book = await db.query.book.findFirst({
157+
where: eq(books.id, id),
158+
with: { notes: true },
159+
});
160+
161+
162+
.. edb:split-section::
163+
164+
**Inserting data:**
165+
166+
.. code-block:: typescript
167+
168+
// Insert a new book
169+
const newBook = await db.insert(book).values({
170+
title: 'The Great Gatsby',
171+
author: 'F. Scott Fitzgerald',
172+
year: 1925,
173+
genre: 'Novel',
174+
}).returning();
175+
176+
// Insert a note for a book
177+
const newNote = await db.insert(note).values({
178+
text: 'A classic novel about the American Dream',
179+
book_id: bookId,
180+
}).returning();
181+
182+
183+
.. edb:split-section::
184+
185+
**Updating data:**
186+
187+
.. code-block:: typescript
188+
189+
// Update a book
190+
const updatedBook = await db.update(book)
191+
.set({
192+
title: 'Updated Title',
193+
author: 'Updated Author',
194+
})
195+
.where(eq(books.id, bookId))
196+
.returning();
197+
198+
199+
.. edb:split-section::
200+
201+
**Deleting data:**
202+
203+
.. code-block:: typescript
204+
205+
// Delete a note
206+
await db.delete(notes).where(eq(notes.id, noteId));
207+
208+
209+
Using Drizzle with Next.js
210+
==========================
211+
212+
.. edb:split-section::
213+
214+
In a Next.js application, you can use your Drizzle client in API routes and server components. Here's an example of an API route that gets all books:
215+
216+
.. code-block:: typescript
217+
:caption: src/app/api/books/route.ts
218+
219+
import { NextResponse } from 'next/server';
220+
import { db } from '@/db';
221+
222+
export async function GET() {
223+
try {
224+
const allBooks = await db.query.book.findMany({
225+
with: { notes: true },
226+
});
227+
228+
return NextResponse.json(allBooks);
229+
} catch (error) {
230+
console.error('Error fetching books:', error);
231+
return NextResponse.json(
232+
{ error: 'Failed to fetch books' },
233+
{ status: 500 }
234+
);
235+
}
236+
}
237+
238+
239+
.. edb:split-section::
240+
241+
And here's an example of using Drizzle in a server component:
242+
243+
.. code-block:: typescript
244+
:caption: src/app/books/page.tsx
245+
246+
import { db } from '@/db';
247+
import BookCard from '@/components/BookCard';
248+
249+
export default async function BooksPage() {
250+
const books = await db.query.book.findMany({
251+
with: { notes: true },
252+
});
253+
254+
return (
255+
<div>
256+
{books.map((book) => (
257+
<BookCard key={book.id} book={book} />
258+
))}
259+
</div>
260+
);
261+
}
262+
263+
264+
Keep going!
265+
===========
266+
267+
You are now ready to use Gel with Drizzle in your applications. This integration gives you the best of both worlds: Gel's powerful features and Drizzle's type-safe, intuitive API.
268+
269+
For a complete example of using Gel with Drizzle in a Next.js application, check out our `Book Notes app example <https://github.com/geldata/gel-examples/tree/main/drizzle-book-notes-app>`_.
270+
271+
You can also find a detailed tutorial on building a Book Notes app with Gel, Drizzle, and Next.js in our :ref:`documentation <ref_guide_gel_drizzle_booknotes>`.

docs/intro/guides/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ Guides
66
:maxdepth: 1
77

88
ai/index
9+
drizzle/index

0 commit comments

Comments
 (0)