From 94025e8c85aa46f4286df722a34201587d3b45d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Pr=C3=B6bstl?= Date: Tue, 13 Oct 2026 16:35:38 +0200 Subject: [PATCH] Update docs for Prisma and Drizzle --- content/clients/javascript/drizzle.md | 316 ++++++++++++------ content/clients/javascript/prisma.md | 301 ++++++++++++----- .../compatibility/ecosystem_and_clients.md | 4 +- 3 files changed, 418 insertions(+), 203 deletions(-) diff --git a/content/clients/javascript/drizzle.md b/content/clients/javascript/drizzle.md index fea704d..237cf1b 100644 --- a/content/clients/javascript/drizzle.md +++ b/content/clients/javascript/drizzle.md @@ -4,47 +4,56 @@ linkTitle: "Drizzle" weight: 10 --- -[Drizzle ORM](https://orm.drizzle.team/) is a TypeScript-first ORM with a SQL-like query API and schema migration tooling. +[Drizzle ORM](https://orm.drizzle.team/) is a TypeScript ORM with a SQL-like query API and the schema migration tool +Drizzle Kit. +CedarDB works with Drizzle's PostgreSQL dialect and the `node-postgres` (`pg`) driver, so you can define your schema, +manage it with migrations, and query it like a PostgreSQL database. +Create and change the schema with `drizzle-kit generate` and `drizzle-kit migrate`. -{{< callout type="info" >}} -Drizzle support is currently **under active development**, already offering **full query API support**. -However, certain advanced features are not yet available. Schema migrations (e.g. via `drizzle-kit push`) might not work as expected. -{{< /callout >}} +This page was tested with `drizzle-orm` 0.45.4, `drizzle-kit` 0.31.11 and `pg` 8.23.1. -The [official getting-started tutorial](https://orm.drizzle.team/docs/get-started/postgresql-new) works out of the box with CedarDB: +This page is a self-contained example that you can follow from start to finish. +It points out what is specific to CedarDB. +For all features, see Drizzle's documentation of +[schemas](https://orm.drizzle.team/docs/sql-schema-declaration), +[migrations](https://orm.drizzle.team/docs/migrations), and +[queries](https://orm.drizzle.team/docs/select). -## Setting up CedarDB +## Prerequisites -Start CedarDB in server mode and create a user and database: +* Node.js 20 or later. +* A running CedarDB server that accepts TCP connections (see [Install CedarDB locally](/docs/get_started/install_locally/)). +* A CedarDB superuser to create the application role and database. -```shell -./cedardb --createdb mydb -psql -h /tmp -U postgres -``` +## Set up CedarDB + +Connect to CedarDB as a superuser and create a role for your application that owns its database: ```sql -create user myuser with password 'CorrectHorseBatteryStaple' superuser; -create database mydb; +CREATE ROLE myuser WITH LOGIN PASSWORD 'CorrectHorseBatteryStaple'; +CREATE DATABASE mydb OWNER myuser; ``` -Then enable TCP connections: +As the database owner, Drizzle can create schemas, tables, and types without further privileges. +This works in every CedarDB edition. +Granting privileges with `GRANT` instead requires a CedarDB [enterprise license](/docs/licensing/). -```shell -./cedardb mydb --address=:: -``` +## Set up the project -For more details, see the [install guide]({{< relref "/get_started/install_locally.md" >}}). +{{% steps %}} -## Installing +### Install Drizzle -Install Drizzle ORM, the `pg` driver, and the Drizzle Kit CLI: +Create a project and install Drizzle ORM, the `pg` driver, and Drizzle Kit: ```shell +mkdir hello-drizzle && cd hello-drizzle +npm init -y npm install drizzle-orm pg dotenv npm install --save-dev drizzle-kit tsx @types/pg ``` -## Connecting +### Configure the connection Create a `.env` file with your CedarDB connection string: @@ -52,130 +61,219 @@ Create a `.env` file with your CedarDB connection string: DATABASE_URL=postgresql://myuser:CorrectHorseBatteryStaple@localhost:5432/mydb ``` -Initialize the Drizzle client in `src/index.ts`: +Create a `drizzle.config.ts` in your project root: -```typescript {filename="src/index.ts"} +```typescript {filename="drizzle.config.ts"} import 'dotenv/config'; -import { drizzle } from 'drizzle-orm/node-postgres'; +import { defineConfig } from 'drizzle-kit'; -const db = drizzle(process.env.DATABASE_URL!); +export default defineConfig({ + out: './drizzle', + schema: './src/db/schema.ts', + dialect: 'postgresql', + dbCredentials: { + url: process.env.DATABASE_URL!, + }, +}); ``` -## Defining a Schema +### Define the schema Create a schema file at `src/db/schema.ts`: ```typescript {filename="src/db/schema.ts"} -import { integer, pgTable, varchar } from "drizzle-orm/pg-core"; +import { boolean, index, integer, pgEnum, pgTable, serial, text, timestamp, varchar } from 'drizzle-orm/pg-core'; + +export const roleEnum = pgEnum('role', ['admin', 'member']); -export const usersTable = pgTable("users", { +export const usersTable = pgTable('users', { id: integer().primaryKey().generatedAlwaysAsIdentity(), name: varchar({ length: 255 }).notNull(), age: integer().notNull(), email: varchar({ length: 255 }).notNull().unique(), + role: roleEnum().default('member').notNull(), }); + +export const postsTable = pgTable('posts', { + id: serial().primaryKey(), + title: text().notNull(), + published: boolean().default(false).notNull(), + createdAt: timestamp().defaultNow().notNull(), + authorId: integer().notNull().references(() => usersTable.id, { onDelete: 'cascade' }), +}, (t) => [index('posts_author_idx').on(t.authorId)]); ``` -Create a `drizzle.config.ts` in your project root: +{{% /steps %}} -```typescript {filename="drizzle.config.ts"} -import 'dotenv/config'; -import { defineConfig } from 'drizzle-kit'; +## Create and change the schema -export default defineConfig({ - out: './drizzle', - schema: './src/db/schema.ts', - dialect: 'postgresql', - dbCredentials: { - url: process.env.DATABASE_URL!, - }, -}); +Drizzle Kit compares your schema file with its own snapshots in the `drizzle` folder and writes the difference as a +SQL migration. +It does not read the CedarDB schema for this, so it works with CedarDB like with PostgreSQL. + +{{% steps %}} + +### Generate the first migration + +```shell +npx drizzle-kit generate +``` + +Drizzle Kit writes the migration to a file such as `drizzle/0000_jazzy_bromley.sql`. +Review the SQL and commit it together with your schema. + +### Apply the migration + +```shell +npx drizzle-kit migrate ``` -## Applying the Schema +Drizzle Kit runs all migrations that are not applied yet and records them in the table +`drizzle.__drizzle_migrations`. -Push the schema to CedarDB using Drizzle Kit: +### Change the schema + +Edit `src/db/schema.ts`, for example add a column to `users` and remove one from `posts`: + +```typescript {filename="src/db/schema.ts"} +export const usersTable = pgTable('users', { + // ... + phone: text(), +}); + +export const postsTable = pgTable('posts', { + id: serial().primaryKey(), + title: text().notNull(), + createdAt: timestamp().defaultNow().notNull(), + authorId: integer().notNull().references(() => usersTable.id, { onDelete: 'cascade' }), +}, (t) => [index('posts_author_idx').on(t.authorId)]); +``` + +Then generate and apply a new migration: ```shell -npx drizzle-kit push +npx drizzle-kit generate +npx drizzle-kit migrate ``` -This creates the `users` table directly in CedarDB without generating migration files. +The migration contains statements such as `ALTER TABLE "users" ADD COLUMN "phone" text` and +`ALTER TABLE "posts" DROP COLUMN "published"`. +CedarDB runs them in place, without recreating the tables. -## Querying +{{% /steps %}} -The full range of Drizzle's query API works with CedarDB: +To apply migrations when your application starts instead of with the CLI, call the migrator from code: -```typescript +```typescript {filename="src/migrate.ts"} import 'dotenv/config'; import { drizzle } from 'drizzle-orm/node-postgres'; -import { and, avg, count, desc, eq, gt, like } from 'drizzle-orm'; -import { usersTable } from './db/schema'; - -const db = drizzle(process.env.DATABASE_URL!); - -// Insert a single row -await db.insert(usersTable).values({ name: 'Alice', age: 28, email: 'alice@example.com' }); - -// Batch insert with RETURNING -const inserted = await db - .insert(usersTable) - .values([ - { name: 'Bob', age: 35, email: 'bob@example.com' }, - { name: 'Carol', age: 22, email: 'carol@example.com' }, - ]) - .returning({ id: usersTable.id, name: usersTable.name }); - -// Filtered select -const result = await db - .select() - .from(usersTable) - .where(and(gt(usersTable.age, 30), like(usersTable.name, '%o%'))); - -// Ordered select with LIMIT -const top2 = await db - .select({ name: usersTable.name, age: usersTable.age }) - .from(usersTable) - .orderBy(desc(usersTable.age)) - .limit(2); - -// Aggregates -const [{ userCount }] = await db.select({ userCount: count() }).from(usersTable); -const [{ avgAge }] = await db.select({ avgAge: avg(usersTable.age) }).from(usersTable); - -// Update -await db.update(usersTable).set({ age: 36 }).where(eq(usersTable.email, 'bob@example.com')); - -// Upsert -await db - .insert(usersTable) - .values({ name: 'Bob', age: 99, email: 'bob@example.com' }) - .onConflictDoUpdate({ target: usersTable.email, set: { age: 99 } }); - -// Transaction -await db.transaction(async (tx) => { - const [user] = await tx - .insert(usersTable) - .values({ name: 'Dave', age: 40, email: 'dave@example.com' }) - .returning({ id: usersTable.id }); - await tx.update(usersTable).set({ age: 41 }).where(eq(usersTable.id, user.id)); -}); +import { migrate } from 'drizzle-orm/node-postgres/migrator'; -// Delete -await db.delete(usersTable).where(eq(usersTable.email, 'alice@example.com')); +async function main() { + const db = drizzle(process.env.DATABASE_URL!); + await migrate(db, { migrationsFolder: './drizzle' }); + await db.$client.end(); +} + +main(); ``` -## Known Limitations +## Query data + +The Drizzle query API works with CedarDB, including relational queries and nested transactions: + +```typescript {filename="src/index.ts"} +import 'dotenv/config'; +import { drizzle } from 'drizzle-orm/node-postgres'; +import { and, avg, count, desc, eq, gt, like, relations } from 'drizzle-orm'; +import { postsTable, usersTable } from './db/schema'; -CedarDB's Drizzle support is actively being developed. The following are known limitations: +const usersRelations = relations(usersTable, ({ many }) => ({ posts: many(postsTable) })); +const postsRelations = relations(postsTable, ({ one }) => ({ + author: one(usersTable, { fields: [postsTable.authorId], references: [usersTable.id] }), +})); -**Schema migrations** (`drizzle-kit push`) are not fully supported. While Drizzle can read an existing CedarDB schema and generate TypeScript definitions from it, it may sometimes not be able to automatically update the schema of an existing database. +const db = drizzle(process.env.DATABASE_URL!, { + schema: { usersTable, postsTable, usersRelations, postsRelations }, +}); -**Raw DDL via `db.execute`** is available as a workaround for schema migrations: +async function main() { + // Batch insert with RETURNING + const [alice] = await db + .insert(usersTable) + .values([ + { name: 'Alice', age: 28, email: 'alice@example.com' }, + { name: 'Bob', age: 35, email: 'bob@example.com' }, + { name: 'Carol', age: 22, email: 'carol@example.com' }, + ]) + .returning({ id: usersTable.id }); + await db.insert(postsTable).values([ + { title: 'Hello CedarDB', authorId: alice.id }, + { title: 'Second post', authorId: alice.id }, + ]); + + // Filtered select + const filtered = await db + .select() + .from(usersTable) + .where(and(gt(usersTable.age, 25), like(usersTable.name, '%o%'))); + + // Ordered select with LIMIT + const oldest = await db + .select({ name: usersTable.name, age: usersTable.age }) + .from(usersTable) + .orderBy(desc(usersTable.age)) + .limit(2); + + // Aggregates + const [{ userCount, avgAge }] = await db + .select({ userCount: count(), avgAge: avg(usersTable.age) }) + .from(usersTable); + + // Relational query: users with their posts + const usersWithPosts = await db.query.usersTable.findMany({ with: { posts: true } }); + + // Upsert + await db + .insert(usersTable) + .values({ name: 'Bob', age: 36, email: 'bob@example.com' }) + .onConflictDoUpdate({ target: usersTable.email, set: { age: 36 } }); + + // Transaction with a nested transaction (savepoint) that rolls back + await db.transaction(async (tx) => { + await tx.update(usersTable).set({ age: 29 }).where(eq(usersTable.id, alice.id)); + try { + await tx.transaction(async (nested) => { + await nested.update(usersTable).set({ age: 99 }).where(eq(usersTable.id, alice.id)); + nested.rollback(); + }); + } catch { + // Alice keeps age 29 + } + }); + + // Delete, cascades to the posts + await db.delete(usersTable).where(eq(usersTable.email, 'alice@example.com')); + + console.log({ filtered, oldest, userCount, avgAge, usersWithPosts }); + await db.$client.end(); +} + +main(); +``` -```typescript -import { sql } from 'drizzle-orm'; +Run the script: -await db.execute(sql`ALTER TABLE users ADD COLUMN phone text`); -await db.execute(sql`ALTER TABLE users DROP COLUMN phone`); +```shell +npx tsx src/index.ts ``` + +## CedarDB limitations + +* `cidr`, `macaddr`, `macaddr8`, and `time with time zone` (`time({ withTimezone: true })`) columns are not supported. +* `numeric` columns support a precision of at most 38, for example `numeric({ precision: 38, scale: 2 })` + (see [Numeric](/docs/references/datatypes/numeric/)). +* Subqueries inside `insert().values()` and renaming enum values are not supported. +* The isolation level `serializable` is not supported. + CedarDB runs all transactions with snapshot isolation and accepts the other isolation levels + (see [Transactions](/docs/references/transactions/)). diff --git a/content/clients/javascript/prisma.md b/content/clients/javascript/prisma.md index a46a7e3..26cfb8a 100644 --- a/content/clients/javascript/prisma.md +++ b/content/clients/javascript/prisma.md @@ -4,50 +4,64 @@ linkTitle: "Prisma" weight: 20 --- -[Prisma ORM](https://www.prisma.io/) is a TypeScript-first ORM with a declarative schema, auto-generated type-safe client, and visual database browser. +[Prisma ORM](https://www.prisma.io/) is a TypeScript ORM with a declarative schema, a generated type-safe client, and +the migration tool Prisma Migrate. +CedarDB works with Prisma's `postgresql` provider and the `@prisma/adapter-pg` driver adapter, so you can define your +schema, manage it with migrations, and query it like a PostgreSQL database. +Apply schema changes with `prisma db push`, or create versioned migrations with `prisma migrate dev` and apply them +with `prisma migrate deploy`. -{{< callout type="info" >}} -Prisma support is currently **under active development**. Automatic schema migrations via `prisma migrate` are not yet supported. Use `npx prisma db push` from a clean database instead. -{{< /callout >}} +This page was tested with `prisma`, `@prisma/client`, and `@prisma/adapter-pg` 7.10.0 and `pg` 8.23.1. -The [official getting-started tutorial](https://www.prisma.io/docs/prisma-orm/quickstart/postgresql) works out of the box with CedarDB, with minor adjustments noted below. +This page is a self-contained example that you can follow from start to finish. +It points out what is specific to CedarDB. +For all features, see Prisma's documentation of +[the Prisma schema](https://www.prisma.io/docs/orm/prisma-schema), +[Prisma Migrate](https://www.prisma.io/docs/orm/prisma-migrate), and +[Prisma Client](https://www.prisma.io/docs/orm/prisma-client). -## Setting up CedarDB +## Prerequisites -Start CedarDB in server mode and create a user and database: +* Node.js 20 or later. +* A running CedarDB server that accepts TCP connections (see [Install CedarDB locally](/docs/get_started/install_locally/)). +* A CedarDB superuser to create the application role and database. -```shell -./cedardb --createdb mydb -psql -h /tmp -U postgres -``` +## Set up CedarDB + +Connect to CedarDB as a superuser and create a role for your application that owns its database: ```sql -create user myuser with password 'CorrectHorseBatteryStaple' superuser; -create database mydb; +CREATE ROLE myuser WITH LOGIN CREATEDB PASSWORD 'CorrectHorseBatteryStaple'; +CREATE DATABASE mydb OWNER myuser; ``` -Then enable TCP connections: +As the database owner, Prisma can create tables, types, and indexes without further privileges. +`CREATEDB` allows `prisma migrate dev` to create and drop a temporary +[shadow database](https://www.prisma.io/docs/orm/prisma-migrate/understanding-prisma-migrate/shadow-database). +If you only use `prisma db push` or `prisma migrate deploy`, you can omit it. +This works in every CedarDB edition. +Granting privileges with `GRANT` instead requires a CedarDB [enterprise license](/docs/licensing/). -```shell -./cedardb mydb --address=:: -``` +## Set up the project -For more details, see the [installation guide]({{< relref "/get_started/install_locally.md" >}}). +{{% steps %}} -## Installing +### Install Prisma -Create a new Node.js project and install Prisma with the PostgreSQL adapter: +Create a Node.js project and install Prisma 7 with the PostgreSQL driver adapter: ```shell mkdir hello-prisma && cd hello-prisma npm init -y -npm install typescript tsx @types/node --save-dev -npx tsc --init -npm install prisma @types/pg --save-dev -npm install @prisma/client @prisma/adapter-pg pg dotenv +npm pkg set type=module +npm install --save-dev prisma@7 typescript tsx @types/node @types/pg +npm install @prisma/client@7 @prisma/adapter-pg@7 pg dotenv ``` -Set `"type": "module"` in `package.json` and configure `tsconfig.json` for ESM: +Pin the major version: the `latest` tag of the `prisma` package can point to a release candidate of the next major +version. + +Create a `tsconfig.json`: ```json {filename="tsconfig.json"} { @@ -62,7 +76,7 @@ Set `"type": "module"` in `package.json` and configure `tsconfig.json` for ESM: } ``` -## Connecting +### Configure the connection Initialize Prisma: @@ -70,32 +84,34 @@ Initialize Prisma: npx prisma init --datasource-provider postgresql --output ../generated/prisma ``` -This creates a `prisma/schema.prisma` and a `.env` file. Set your CedarDB connection string in `.env`: +Set your CedarDB connection string in `.env`: ```shell {filename=".env"} DATABASE_URL="postgresql://myuser:CorrectHorseBatteryStaple@localhost:5432/mydb?schema=public" ``` -Instantiate the Prisma client in `lib/prisma.ts`: +Make sure `prisma.config.ts` loads the connection string: -```typescript {filename="lib/prisma.ts"} +```typescript {filename="prisma.config.ts"} import "dotenv/config"; -import { PrismaPg } from "@prisma/adapter-pg"; -import { PrismaClient } from "../generated/prisma/client"; - -const connectionString = `${process.env.DATABASE_URL}`; - -const adapter = new PrismaPg({ connectionString }); -const prisma = new PrismaClient({ adapter }); - -export { prisma }; +import { defineConfig } from "prisma/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + }, + datasource: { + url: process.env["DATABASE_URL"], + }, +}); ``` -## Defining a Schema +### Define the schema Edit `prisma/schema.prisma` to define your models: -```prisma {filename="prisma/schema.prisma"} +``` {filename="prisma/schema.prisma"} generator client { provider = "prisma-client" output = "../generated/prisma" @@ -105,10 +121,16 @@ datasource db { provider = "postgresql" } +enum Role { + ADMIN + MEMBER +} + model User { id Int @id @default(autoincrement()) email String @unique name String? + role Role @default(MEMBER) posts Post[] } @@ -117,61 +139,176 @@ model Post { title String content String? published Boolean @default(false) - author User @relation(fields: [authorId], references: [id]) + price Decimal @default(0) @db.Decimal(10, 2) + author User @relation(fields: [authorId], references: [id], onDelete: Cascade) authorId Int + + @@index([authorId]) } ``` -## Applying the Schema +### Create the client -Push the schema to CedarDB using `prisma db push` (note: `prisma migrate` is not yet supported): +Instantiate Prisma Client with the driver adapter in `lib/prisma.ts`: + +```typescript {filename="lib/prisma.ts"} +import "dotenv/config"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { PrismaClient } from "../generated/prisma/client"; + +const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }); +const prisma = new PrismaClient({ adapter }); + +export { prisma }; +``` + +{{% /steps %}} + +## Create and change the schema + +Choose one of two workflows: + +* **`prisma db push`** applies the schema directly, without migration files. + Use it for prototyping. +* **Versioned migrations** with `prisma migrate dev` keep every change as a SQL file that you review and commit. + `prisma migrate deploy` applies them to other environments, such as production. + +### Push the schema + +Push the schema to CedarDB and generate Prisma Client: ```shell npx prisma db push +npx prisma generate ``` -Then generate the Prisma client: +After you change `prisma/schema.prisma`, run both commands again. +Prisma compares the schema with the tables in CedarDB and applies only the difference, for example with +`ALTER TABLE ... ADD COLUMN` or `DROP COLUMN`. +If a change can lose data, Prisma asks for confirmation. + +### Use versioned migrations + +{{% steps %}} + +#### Create the first migration + +Create a migration from the schema, apply it, and generate Prisma Client: ```shell +npx prisma migrate dev --name init npx prisma generate ``` -## Querying +Prisma Migrate writes the SQL to `prisma/migrations/_init/migration.sql` and records the applied migration +in the table `_prisma_migrations`. + +#### Change the schema -Create a `script.ts` to run queries against CedarDB: +Edit `prisma/schema.prisma`, for example add a field to `User`: + +```prisma {filename="prisma/schema.prisma"} +model User { + // ... + createdAt DateTime @default(now()) @db.Timestamp(6) +} +``` + +CedarDB stores timestamps with microsecond precision. +Declare `DateTime` fields with `@db.Timestamp(6)` so that the column type matches, because Prisma uses `timestamp(3)` +by default. + +Create and apply a migration for the change: + +```shell +npx prisma migrate dev --name add_created_at +npx prisma generate +``` + +Review each migration before you commit it. + +#### Deploy the migrations + +Apply all pending migrations to another database, for example in production: + +```shell +npx prisma migrate deploy +``` + +`prisma migrate deploy` does not need a shadow database. + +{{% /steps %}} + +### Reset a development database + +To start over, drop and recreate the database, then push the schema or apply the migrations again: + +```sql +DROP DATABASE mydb; +CREATE DATABASE mydb OWNER myuser; +``` + +## Query data + +Create a `script.ts` that runs queries against CedarDB: ```typescript {filename="script.ts"} import { prisma } from "./lib/prisma"; async function main() { - // Create a user with a related post - const user = await prisma.user.create({ + // Start from empty tables, deletes cascade to the posts + await prisma.user.deleteMany(); + + // Create a user with related posts + const alice = await prisma.user.create({ data: { name: "Alice", email: "alice@prisma.io", posts: { - create: { - title: "Hello World", - content: "This is my first post!", - published: true, - }, + create: [ + { title: "Hello World", content: "This is my first post!", published: true, price: "9.99" }, + { title: "Draft" }, + ], }, }, - include: { - posts: true, - }, }); - console.log("Created user:", user); - // Fetch all users with their posts - const allUsers = await prisma.user.findMany({ - include: { posts: true }, + // Filter on a relation and count related records + const authors = await prisma.user.findMany({ + where: { posts: { some: { published: true } } }, + select: { email: true, _count: { select: { posts: true } } }, }); - console.log("All users:", JSON.stringify(allUsers, null, 2)); + + // Aggregate and group + const stats = await prisma.post.aggregate({ _sum: { price: true }, _count: true }); + const byRole = await prisma.user.groupBy({ by: ["role"], _count: { _all: true } }); + + // Interactive transaction + await prisma.$transaction(async (tx) => { + const bob = await tx.user.create({ data: { email: "bob@prisma.io", name: "Bob" } }); + await tx.post.create({ data: { title: "Bob's post", authorId: bob.id } }); + }); + + // Upsert + await prisma.user.upsert({ + where: { email: "bob@prisma.io" }, + update: { role: "ADMIN" }, + create: { email: "bob@prisma.io", role: "ADMIN" }, + }); + + // Fetch all users with their posts + const allUsers = await prisma.user.findMany({ include: { posts: true }, orderBy: { id: "asc" } }); + + // Delete, cascades to the posts + await prisma.user.delete({ where: { id: alice.id } }); + + console.log(JSON.stringify({ authors, stats, byRole, allUsers }, null, 2)); } main() - .then(async () => { await prisma.$disconnect(); }) + .then(async () => { + await prisma.$disconnect(); + }) .catch(async (e) => { console.error(e); await prisma.$disconnect(); @@ -182,36 +319,16 @@ main() Run the script: ```shell -$ npx tsx script.ts -User created successfully. -All users: [ - { - "id": 1, - "email": "alice@prisma.io", - "name": "Alice", - "posts": [ - { - "id": 1, - "title": "Hello World", - "content": "This is my first post!", - "published": true, - "authorId": 1 - } - ] - } -] +npx tsx script.ts ``` -## Known Limitations +## CedarDB limitations -CedarDB's Prisma support is actively being developed. The following are known limitations: - -**Schema migrations** (`prisma migrate dev`) are not supported. Use `npx prisma db push` to apply schema changes directly to the database instead. - -**Drop database** of non-empty databases is not supported. To reset your database, manually drop all contained objects and recreate it via `psql`: - -```sql - -drop database mydb; -create database mydb; -``` +* `Decimal` fields without a native type are created as `decimal(65,30)`, which exceeds the maximum precision of 38 + (see [Numeric](/docs/references/datatypes/numeric/)). + Add a native type with a precision of at most 38, for example `@db.Decimal(10, 2)`. +* `@db.Xml`, `@db.Timetz`, `@db.Cidr`, and `@db.MacAddr` fields are not supported. +* Full-text search (the `fullTextSearchPostgres` preview feature) is not supported. +* The isolation level `Serializable` is not supported. + CedarDB runs all transactions with snapshot isolation and accepts the other isolation levels + (see [Transactions](/docs/references/transactions/)). diff --git a/content/compatibility/ecosystem_and_clients.md b/content/compatibility/ecosystem_and_clients.md index 3ddad1f..7d53260 100644 --- a/content/compatibility/ecosystem_and_clients.md +++ b/content/compatibility/ecosystem_and_clients.md @@ -39,8 +39,8 @@ range of PostgreSQL connectors for end-user tools like Grafana and programming l | C++ | libpqxx | 7.9.1 | Full | [Documentation](/docs/clients/cpp/) | | Java | JDBC | 42.7.4 | Full | [Documentation](/docs/clients/java/) | | JavaScript | node-postgres | 8.13.0 | Full | [Documentation](/docs/clients/javascript/) | -| | drizzle-orm | 0.45.1 | Partial | [Documentation](/docs/clients/javascript/drizzle/) | -| | prisma-orm | 7.7.0 | Partial | [Documentation](/docs/clients/javascript/prisma/) | +| | drizzle-orm | 0.45.4 | Partial | [Documentation](/docs/clients/javascript/drizzle/) | +| | prisma-orm | 7.10.0 | Partial | [Documentation](/docs/clients/javascript/prisma/) | | Python | psycopg2 | 2.9.10 | Full | | | | psycopg | 3.2.3 | Full | [Documentation](/docs/clients/python/) | | R | RPostgres | 1.4.7 | Full | [Documentation](/docs/clients/r/) |