Skip to content

Commit f9f49a0

Browse files
author
Aleksandra
authored
Add quick drizzle guide (#8648)
1 parent 2d9f562 commit f9f49a0

File tree

3 files changed

+311
-0
lines changed

3 files changed

+311
-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: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
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,
124+
schema: {
125+
...schema,
126+
...relations
127+
},
128+
});
129+
130+
// Helper types for use in our application
131+
export type Book = typeof schema.book.$inferSelect;
132+
export type NewBook = typeof schema.book.$inferInsert;
133+
134+
export type Note = typeof schema.note.$inferSelect;
135+
export type NewNote = typeof schema.note.$inferInsert;
136+
137+
138+
Perform database operations with Drizzle
139+
========================================
140+
141+
For more detailed information on querying and other operations, refer to the `Drizzle documentation <https://orm.drizzle.team/docs/rqb>`_. Below are some examples of common database operations you can perform with Drizzle.
142+
143+
.. edb:split-section::
144+
145+
Drizzle provides a clean, type-safe API for database operations. Here are some examples of common operations:
146+
147+
**Selecting data:**
148+
149+
.. code-block:: typescript
150+
151+
// Get all books with their notes
152+
const allBooks = await db.query.book.findMany({
153+
with: {
154+
notes: true,
155+
},
156+
});
157+
158+
// Get a specific book
159+
const book = await db.query.book.findFirst({
160+
where: eq(books.id, id),
161+
with: { notes: true },
162+
});
163+
164+
165+
.. edb:split-section::
166+
167+
**Inserting data:**
168+
169+
.. code-block:: typescript
170+
171+
// Insert a new book
172+
const newBook = await db.insert(book).values({
173+
title: 'The Great Gatsby',
174+
author: 'F. Scott Fitzgerald',
175+
year: 1925,
176+
genre: 'Novel',
177+
}).returning();
178+
179+
// Insert a note for a book
180+
const newNote = await db.insert(note).values({
181+
text: 'A classic novel about the American Dream',
182+
book_id: newBook.bookId,
183+
}).returning();
184+
185+
**Bulk inserting data:**
186+
187+
.. code-block:: typescript
188+
189+
// Insert multiple books at once
190+
const newBooks = await db.insert(book).values([
191+
{
192+
title: '1984',
193+
author: 'George Orwell',
194+
year: 1949,
195+
genre: 'Dystopian',
196+
},
197+
{
198+
title: 'To Kill a Mockingbird',
199+
author: 'Harper Lee',
200+
year: 1960,
201+
genre: 'Fiction',
202+
},
203+
{
204+
title: 'Pride and Prejudice',
205+
author: 'Jane Austen',
206+
year: 1813,
207+
genre: 'Romance',
208+
},
209+
]).returning();
210+
211+
.. edb:split-section::
212+
213+
**Updating data:**
214+
215+
.. code-block:: typescript
216+
217+
// Update a book
218+
const updatedBook = await db.update(book)
219+
.set({
220+
title: 'Updated Title',
221+
author: 'Updated Author',
222+
})
223+
.where(eq(books.id, bookId))
224+
.returning();
225+
226+
227+
.. edb:split-section::
228+
229+
**Deleting data:**
230+
231+
.. code-block:: typescript
232+
233+
// Delete a note
234+
await db.delete(notes).where(eq(notes.id, noteId));
235+
236+
237+
Using Drizzle with Next.js
238+
==========================
239+
240+
.. edb:split-section::
241+
242+
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:
243+
244+
.. code-block:: typescript
245+
:caption: src/app/api/books/route.ts
246+
247+
import { NextResponse } from 'next/server';
248+
import { db } from '@/db';
249+
250+
export async function GET() {
251+
try {
252+
const allBooks = await db.query.book.findMany({
253+
with: { notes: true },
254+
});
255+
256+
return NextResponse.json(allBooks);
257+
} catch (error) {
258+
console.error('Error fetching books:', error);
259+
return NextResponse.json(
260+
{ error: 'Failed to fetch books' },
261+
{ status: 500 }
262+
);
263+
}
264+
}
265+
266+
267+
.. edb:split-section::
268+
269+
And here's an example of using Drizzle in a server component:
270+
271+
.. code-block:: typescript
272+
:caption: src/app/books/page.tsx
273+
274+
import { db } from '@/db';
275+
import BookCard from '@/components/BookCard';
276+
277+
export default async function BooksPage() {
278+
const books = await db.query.book.findMany({
279+
with: { notes: true },
280+
});
281+
282+
return (
283+
<div>
284+
{books.map((book) => (
285+
<BookCard key={book.id} book={book} />
286+
))}
287+
</div>
288+
);
289+
}
290+
291+
292+
Keep going!
293+
===========
294+
295+
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.
296+
297+
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>`_.
298+
299+
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)