Skip to content
Closed
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
190c954
orange tutorial
lroal Feb 21, 2025
b5db0d7
typos
lroal Feb 21, 2025
10d0496
jsonc
lroal Feb 21, 2025
7f839dc
typos
lroal Feb 21, 2025
c107730
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
lroal Feb 21, 2025
4ccae3e
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
lroal Feb 25, 2025
e45f161
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 25, 2025
becc38d
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 25, 2025
c1c721c
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 25, 2025
e94698a
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 25, 2025
8b22133
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 25, 2025
bd95525
Apply suggestions from code review
Oxyjun Feb 25, 2025
5e17422
Apply suggestions from code review
Oxyjun Feb 25, 2025
cce3a72
Apply suggestions from code review
Oxyjun Feb 25, 2025
d8d5a2f
Apply suggestions from code review
Oxyjun Feb 25, 2025
9d6d19d
Apply suggestions from code review
Oxyjun Feb 25, 2025
f15cc37
Apply suggestions from code review
Oxyjun Feb 25, 2025
70e04cc
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 25, 2025
9c3a2e1
Apply suggestions from code review
Oxyjun Feb 25, 2025
86ab52c
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 26, 2025
d773abf
Apply suggestions from code review part 1
Oxyjun Feb 26, 2025
b217f70
Apply suggestions from code review part 2
Oxyjun Feb 26, 2025
d815c8e
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 28, 2025
0e32987
Update src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Oxyjun Feb 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
276 changes: 276 additions & 0 deletions src/content/docs/d1/tutorials/d1-and-orange-orm/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
---
updated: 2025-02-21
difficulty: Beginner
content_type: Tutorial
pcx_content_type: tutorial
title: Query D1 using Orange ORM
description: Use Orange ORM to query a D1 database.
products:
- Workers
languages:
- TypeScript
- SQL
---

import { WranglerConfig, PackageManagers, Render, FileTree } from "~/components";

:::note
This is a community-created tutorial.
:::

## What is Orange ORM?

Orange ORM is an Object Relational Mapper for TypeScript, offering seamless integration with a variety of popular databases. Orange ORM supports both TypeScript and JavaScript, including both CommonJS and ECMAScript.

Refer to the full [Orange ORM documentation](https://github.com/alfateam/orange-orm) for more information.


## Query D1 from a Cloudflare Worker using Orange ORM

This example shows you how to set up and deploy a Cloudflare Worker that is accessing a D1 database from scratch.

### Prerequisites

- [`Node.js`](https://nodejs.org/en/) and [`npm`](https://docs.npmjs.com/getting-started) installed on your machine.
- A [Cloudflare account](https://dash.cloudflare.com).

### 1. Create a Cloudflare Worker

Open your terminal and create a Cloudflare Worker:

1. Create a Worker named `orange-d1-example` by running:

<PackageManagers type="create" pkg="cloudflare@latest" args={"orange-d1-example"} />

<Render
file="c3-post-run-steps"
product="workers"
params={{
category: "hello-world",
type: "Hello World Worker",
lang: "TypeScript",
}}
/>

2. Change into your new project directory to start developing:

```sh
cd orange-d1-example
```

### 2. Install Orange ORM

:::note

D1 is supported in Orange ORM as of [v4.5.0](https://github.com/alfateam/orange-orm/releases/tag/v4.5.0).

:::

```sh
npm install orange-orm
```


### 3. Create your D1 database

You can create a D1 database via the [Cloudflare dashboard](https://dash.cloudflare.com), or via `wrangler`. This tutorial uses the `wrangler` CLI.

Open your terminal and run the following command:

```sh
npx wrangler d1 create orange-demo-db
```

You should receive the following output on your terminal:

```txt
✅ Successfully created DB 'orange-demo-db' in region EEUR
Created your database using D1's new storage backend. The new storage backend is not yet recommended for production workloads, but backs up your data via
point-in-time restore.

{
"d1_databases": [
{
"binding": "DB",
"database_name": "orange-demo-db",
"database_id": "<YOUR_D1_DATABASE_ID>"
}
]
}
```

You now have a D1 database in your Cloudflare account with a binding to your Cloudflare Worker.

Copy the JSON snippet from the command output and paste it into your `wrangler.jsonc` file. Your `wrangler.jsonc` file should look similar to the following:

<WranglerConfig>

```jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "orange-d1-example",
"main": "src/index.ts",
"compatibility_date": "2025-02-14",
"observability": {
"enabled": true
},
"d1_databases": [
{
"binding": "DB",
"database_name": "orange-demo-db",
"database_id": "<YOUR_D1_DATABASE_ID>"
}
]
}
```

</WranglerConfig>

Replace `<YOUR_D1_DATABASE_ID>` with the database ID of your D1 instance. If you were not able to fetch this ID from the terminal output, you can also find it in the [Cloudflare dashboard](https://dash.cloudflare.com/), or by running `npx wrangler d1 info orange-demo-db` in your terminal.

Next, create a database table in the database to send queries to D1 using Orange ORM.

### 4. Create a table in the database

D1 has a [migration system](/d1/reference/migrations/), and in the following steps, you will use D1's migration system to create and run a migration against your database.

1. Create a new migration using `wrangler`:

```sh
npx wrangler d1 migrations create orange-demo-db create_user_table
```

2. When asked to create a new folder called `migrations`, enter `Y`.

The command has now created a new directory called `migrations` and an empty file called `0001_create_user_table.sql` inside of it:

<FileTree>
- migrations
- **0001_create_user_table.sql**
</FileTree>

3. Edit the file so it looks like this:

```sql
-- CreateTable
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"name" TEXT
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
```

You now need to use the `wrangler d1 migrations apply` command to send this SQL statement to D1. This command accepts two flags:

- `--local`: Executes the statement against a local version of D1. This local version of D1 is a SQLite database file that will be located in the `.wrangler/state` directory of your project. Use this approach when you want to develop and test your Worker on your local machine. Refer to [Local development](/d1/best-practices/local-development/) to learn more.
- `--remote`: Executes the statement against your remote version of D1. This version is used by your deployed Cloudflare Workers. Refer to [Remote development](/d1/best-practices/remote-development/) to learn more.

In this tutorial, you will first test the Worker locally, then deploy your Worker.

4. Open your terminal, and run both commands:

```sh
# For the local database
npx wrangler d1 migrations apply orange-demo-db --local
```

```sh
# For the remote database
npx wrangler d1 migrations apply orange-demo-db --remote
```

Choose `Yes` both times when you are prompted to confirm that the migration should be applied.

5. Next, create some data that you can query once the Worker is running. This time, you will run the SQL statement without storing it in a file. Run the following commands:

```sh
# For the local database
npx wrangler d1 execute orange-demo-db --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('[email protected]', 'Jane Doe (Local)');" --local
```

```sh
# For the remote database
npx wrangler d1 execute orange-demo-db --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('[email protected]', 'Jane Doe (Remote)');" --remote
```

### 5. Query your database from the Worker

To query your database from the Worker using Orange ORM, you need to:

1. Create a `src/map.ts` file with the following code:

```ts
import orange from 'orange-orm';

const map = orange.map(x => ({
user: x.table('user').map(({ column }) => ({
id: column('id').numeric().primary(),
email: column('email').string(),
name: column('name').string(),
}))
}));

export default map;
```

2. Instantiate the `orange-orm` with the D1 instance, then send a query using the Orange client and return the result. To do this in the code, open `src/index.ts` and replace the entire content with the following:

```ts
import map from './map';

export interface Env {
DB: D1Database;
}
export default {
async fetch(request, env, ctx): Promise<Response> {
const db = map.d1(env.DB);
const users = await db.user.getAll();
return Response.json(users);
},
} satisfies ExportedHandler<Env>;
```



### 6. Run the Worker locally

1. Run the Worker locally by running the following command:

```sh
npm run dev
```

2. Open your browser at [`http://localhost:8787`](http://localhost:8787/) to check the result of the database query. You should see the following JSON block:

```json
[{ "id": 1, "email": "[email protected]", "name": "Jane Doe (Local)" }]
```

### 7. Deploy the Worker

To deploy the Worker, run the following command:

```sh
npm run deploy
```

Access your Worker at `https://orange-d1-example.USERNAME.workers.dev`. Your browser should display the following data queried from your remote D1 database:

```json
[{ "id": 1, "email": "[email protected]", "name": "Jane Doe (Remote)" }]
```

### Summary

By finishing this tutorial, you have deployed a Cloudflare Worker using D1 as a database and querying it via Orange ORM.

## Related resources

- [Orange ORM documentation](https://github.com/alfateam/orange-orm).
- To get help, open a new [GitHub Discussion](https://github.com/alfateam/orange-orm/discussions).
- Check out the [Discord](https://discord.gg/QjuEgvQXzd).
- Watch the [youtube video](https://youtu.be/1IwwjPr2lMs).
- Watch the [interview with the author](https://www.youtube.com/watch?v=roCK6HQlyHQ).