Use Prisma ORM with Appwrite Postgres_
Model your data with Prisma ORM, generate a typed client, and test schema migrations against Appwrite Postgres.

ORMs are a popular way to work with database records as objects in application code. With Appwrite Postgres, you can use Prisma ORM to describe your data in a schema file and generate a TypeScript client for it.
This guide uses a small reading list to put that workflow into practice. You'll save bookmarks, query unread links, and add priorities through a migration. The database runs on Appwrite Cloud, while Prisma ORM handles the models, queries, and migration files.
Provision Postgres
Open your project at appwrite.io, then choose Databases → Create database. Select PostgreSQL under Native databases.

Name the database Reading list, keep the automatically generated ID, and choose Starter. Leave replicas and PITR off for this example. Review the configuration and price, then click Create database. The PostgreSQL quick start covers the available options.
Once provisioning finishes, the SQL editor opens. The sidebar gives you access to your tables and connection credentials.

Configure Prisma ORM
Open Credentials, select DSN, and copy the connection string.

This example uses Prisma ORM 7. Install the client, PostgreSQL adapter, and CLI in your TypeScript project:
npm install @prisma/client@7.10.0 @prisma/adapter-pg@7.10.0 dotenv pgnpm install --save-dev prisma@7.10.0 typescript tsx @types/node @types/pgnpx prisma init --datasource-provider postgresql --output ../generated/prismaUse "type": "module" in package.json. In .env, set DATABASE_URL to the copied connection string with port 5432. We use this direct endpoint for migrations because they can depend on a consistent database session. Port 6432 uses the connection pooler. Keep the other connection values and TLS settings unchanged, and keep .env out of Git. See connection options.
DATABASE_URL="postgresql://<USER>:<PASSWORD>@<HOST>:5432/<DATABASE>?sslmode=require"Update the generated prisma7.config.ts:
import "dotenv/config";import { defineConfig, env } from "prisma/config";
export default defineConfig({ schema: "prisma/schema.prisma", migrations: { path: "prisma/migrations" }, datasource: { url: env("DATABASE_URL"), },});Describe the bookmarks
Prisma ORM models live in prisma/schema.prisma. Each model defines fields and constraints that Prisma Migrate translates into a database table. Replace the generated schema with:
generator client { provider = "prisma-client" output = "../generated/prisma"}
datasource db { provider = "postgresql"}
model Bookmark { id Int @id @default(autoincrement()) title String url String @unique read Boolean @default(false)
@@map("bookmarks")}@unique prevents duplicate URLs. @default(false) makes new bookmarks unread, and @@map("bookmarks") gives the table a lowercase name while keeping the client API as prisma.bookmark.
Generate SQL for the empty database and save it as the first migration:
mkdir -p prisma/migrations/0001_create_bookmarksnpx prisma migrate diff \ --from-empty \ --to-schema prisma/schema.prisma \ --script \ --output prisma/migrations/0001_create_bookmarks/migration.sqlReview migration.sql, then apply it and generate Prisma Client:
npx prisma migrate deploynpx prisma generatemigrate diff produces SQL, migrate deploy applies pending migrations, and generate builds the client from your model. Commit prisma/migrations with your schema and configuration so other environments can apply the same changes.
In Appwrite, choose Data → public, refresh the table list, and open bookmarks → Columns. The table should have id, title, url, and read.

Save and query bookmarks
Create src/db.ts to connect the generated client to Postgres through the driver adapter:
import "dotenv/config";import { PrismaPg } from "@prisma/adapter-pg";import { PrismaClient } from "../generated/prisma/client";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! });export const prisma = new PrismaClient({ adapter });The following examples are standalone scripts, so they disconnect when finished. In a server application, reuse Prisma Client across requests and disconnect at shutdown.
Create src/bookmarks.ts:
import { prisma } from "./db";
try { await prisma.bookmark.createMany({ data: [ { title: "Postgres quick start", url: "https://appwrite.io/docs/products/databases/postgresql/quick-start", }, { title: "Prisma ORM integration", url: "https://appwrite.io/docs/products/databases/postgresql/integrations/prisma", }, { title: "Database branches", url: "https://appwrite.io/docs/products/databases/postgresql/branches", }, ], skipDuplicates: true, });
const unread = await prisma.bookmark.findMany({ where: { read: false }, select: { title: true, url: true }, orderBy: { title: "asc" }, });
console.table(unread);} finally { await prisma.$disconnect();}Run npx tsx src/bookmarks.ts. The result lists Database branches, Postgres quick start, and Prisma ORM integration in title order. Running the script again skips the existing URLs. The where, select, and orderBy options are typed from your model.
Add priorities with a migration
Add this field to Bookmark in prisma/schema.prisma:
priority Int @default(0)Compare the database with your updated model and save the next migration:
mkdir -p prisma/migrations/0002_add_prioritynpx prisma migrate diff \ --from-config-datasource \ --to-schema prisma/schema.prisma \ --script \ --output prisma/migrations/0002_add_priority/migration.sqlOpen the new migration.sql under prisma/migrations. It adds the column with a default for existing bookmarks:
ALTER TABLE "bookmarks" ADD COLUMN "priority" INTEGER NOT NULL DEFAULT 0;Apply the migration and regenerate the client so its types include priority:
npx prisma migrate deploynpx prisma generateRefresh Columns in Appwrite. The new priority column has a default of 0, and the three bookmarks are still present.

Choose what to read next
Create src/prioritize.ts to mark the quick start as read and move the Prisma ORM integration to the top of the remaining list:
import { prisma } from "./db";
try { await prisma.bookmark.update({ where: { url: "https://appwrite.io/docs/products/databases/postgresql/quick-start", }, data: { read: true }, });
await prisma.bookmark.update({ where: { url: "https://appwrite.io/docs/products/databases/postgresql/integrations/prisma", }, data: { priority: 2 }, });
const next = await prisma.bookmark.findMany({ where: { read: false }, select: { title: true, priority: true }, orderBy: [{ priority: "desc" }, { title: "asc" }], });
console.table(next);} finally { await prisma.$disconnect();}Run npx tsx src/prioritize.ts. Prisma ORM integration appears first with priority 2, followed by Database branches with priority 0. Postgres quick start is excluded because it is marked as read.
Open Rows in Appwrite and refresh to inspect the saved values.

Bring the model into your application
Prisma ORM gives you a query API generated from your schema, with types that help catch invalid fields and values during development. Prisma Migrate keeps database changes in SQL files you can review and deploy alongside the application code that uses them.
You can use the same approach in a production application backed by Appwrite Postgres. Test changes against an isolated database branch, then apply committed migrations during deployment with npx prisma migrate deploy.





