Skip to content

Neon es un Postgres serverless totalmente gestionado que separa cómputo y almacenamiento para ofrecer características como autoescalado, ramificación y almacenamiento ilimitado. Neon se puede usar desde Bun directamente usando el controlador @neondatabase/serverless o a través de un ORM como Drizzle.

Drizzle ORM soporta tanto una API de "constructor de consultas" similar a SQL como una API de Consultas similar a ORM. Comienza creando un directorio de proyecto, inicializando el directorio usando bun init, e instalando Drizzle y el controlador serverless de Neon.

sh
mkdir bun-drizzle-neon
cd bun-drizzle-neon
bun init -y
bun add drizzle-orm @neondatabase/serverless
bun add -D drizzle-kit

Crea un archivo .env.local y agrega tu cadena de conexión de Neon Postgres.

ini
DATABASE_URL=postgresql://usertitle:password@ep-adj-noun-guid.us-east-1.aws.neon.tech/neondb?sslmode=require

Nos conectaremos a la base de datos Neon usando el controlador serverless de Neon, envuelto en una instancia de base de datos Drizzle.

ts
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";

// Bun carga automáticamente DATABASE_URL desde .env.local
// Consulta: https://bun.com/docs/runtime/environment-variables para más información
const sql = neon(process.env.DATABASE_URL!);

export const db = drizzle(sql);

Para ver la base de datos en acción, agrega estas líneas a index.ts.

ts
import { db } from "./db";
import { sql } from "drizzle-orm";

const query = sql`select 'hello world' as text`;
const result = await db.execute(query);
console.log(result.rows);

Luego ejecuta index.ts con Bun.

sh
bun run index.ts
txt
[
  {
    text: "hello world",
  }
]

Podemos definir un esquema para nuestra base de datos usando primitivos de Drizzle ORM. Crea un archivo schema.ts y agrega este código.

ts
import { pgTable, integer, serial, text, timestamp } from "drizzle-orm/pg-core";

export const authors = pgTable("authors", {
  id: serial("id").primaryKey(),
  title: text("name").notNull(),
  bio: text("bio"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
});

Luego usamos el CLI drizzle-kit para generar una migración SQL inicial.

sh
bunx drizzle-kit generate --dialect postgresql --schema ./schema.ts --out ./drizzle

Esto crea un nuevo directorio drizzle que contiene un archivo de migración .sql y el directorio meta.

txt
drizzle
├── 0000_aspiring_post.sql
└── meta
    ├── 0000_snapshot.json
    └── _journal.json

Podemos ejecutar estas migraciones con un script simple migrate.ts. Este script crea una nueva conexión a la base de datos Neon y ejecuta todas las migraciones no ejecutadas en el directorio drizzle.

ts
import { db } from "./db";
import { migrate } from "drizzle-orm/neon-http/migrator";

const main = async () => {
  try {
    await migrate(db, { migrationsFolder: "drizzle" });
    console.log("Migration completed");
  } catch (error) {
    console.error("Error during migration:", error);
    process.exit(1);
  }
};

main();

Podemos ejecutar este script con bun para ejecutar la migración.

sh
bun run migrate.ts
txt
Migration completed

Ahora podemos agregar algunos datos a nuestra base de datos. Crea un archivo seed.ts con el siguiente contenido.

ts
import { db } from "./db";
import * as schema from "./schema";

async function seed() {
  await db.insert(schema.authors).values([
    {
      title: "J.R.R. Tolkien",
      bio: "The creator of Middle-earth and author of The Lord of the Rings.",
    },
    {
      title: "George R.R. Martin",
      bio: "The author of the epic fantasy series A Song of Ice and Fire.",
    },
    {
      title: "J.K. Rowling",
      bio: "The creator of the Harry Potter series.",
    },
  ]);
}

async function main() {
  try {
    await seed();
    console.log("Seeding completed");
  } catch (error) {
    console.error("Error during seeding:", error);
    process.exit(1);
  }
}

main();

Luego ejecuta este archivo.

sh
bun run seed.ts
txt
Seeding completed

Ahora tenemos una base de datos con un esquema y datos de ejemplo. Podemos usar Drizzle para consultarla. Reemplaza el contenido de index.ts con lo siguiente.

ts
import * as schema from "./schema";
import { db } from "./db";

const result = await db.select().from(schema.authors);
console.log(result);

Luego ejecuta el archivo. Deberías ver los tres autores que insertamos.

sh
bun run index.ts
txt
[
  {
    id: 1,
    title: "J.R.R. Tolkien",
    bio: "The creator of Middle-earth and author of The Lord of the Rings.",
    createdAt: 2024-05-11T10:28:46.029Z,
  }, {
    id: 2,
    title: "George R.R. Martin",
    bio: "The author of the epic fantasy series A Song of Ice and Fire.",
    createdAt: 2024-05-11T10:28:46.029Z,
  }, {
    id: 3,
    title: "J.K. Rowling",
    bio: "The creator of the Harry Potter series.",
    createdAt: 2024-05-11T10:28:46.029Z,
  }
]

Este ejemplo usó la funcionalidad SQL-over-HTTP del controlador serverless de Neon. El controlador serverless de Neon también expone los constructores Client y Pool para habilitar sesiones, transacciones interactivas y compatibilidad con node-postgres. Consulta la documentación de Neon para una visión completa.

Consulta el sitio web de Drizzle para más documentación sobre el uso de Drizzle ORM.

Bun por www.bunjs.com.cn editar