DEV Community

Cover image for Get started with Prisma ORM and Xata's Postgres service
Cezzaine Zaher for Xata

Posted on • Originally published at xata.io

Get started with Prisma ORM and Xata's Postgres service

Prisma is a very popular Node.js and TypeScript ORM that provides type safe access to your database, automated migrations, and a custom data model definition.

With this week's beta release of Xata's Postgres service you are now able to connect to your Xata database with Prisma over the Postgres wire protocol. You can simply use the default Prisma ORM connector or Prisma driver adapters (@prisma/adapter-pg).

Setting up with Xata

Before starting you will need an empty Xata database that has direct access to Postgres enabled.

Creating a new database

You will first need to enable direct access to Postgres in your workspace settings.

Enable direct access for your workspace

You will also need to enable direct access to Postgres when you create your new database.

Enable direct access for your database

After this point you will be able to see your Xata database connection string when navigating to database settings. It will look like this:

postgresql://<YOUR_WORKSPACE_ID>:<YOUR_API_KEY>@<YOUR_REGION>.sql.xata.sh:5432/<YOUR_DATABASE_NAME>:<YOUR_BRANCH_NAME>
Enter fullscreen mode Exit fullscreen mode

Keep a copy of this somewhere safe and secure for later use in your Prisma application.

Generating some tables via CSV

You’ll want some tables that contain data, we recommend using the examples in the xata-py repo. For the example here we’ll use companies_med_250 and prices_med_2500. These can imported via the Import CSV function in the web application.

Setting up with Prisma

There are two ways to set up Prisma: using the default ORM connector or the Driver Adapters. If you are using the Driver Adapters you will need to follow a few additional steps.

Scaffold a Prisma project by following their from scratch setup guide.

After completing their setup guide, a .env file should be created at the root of your project with a variable named DATABASE_URL. Replace that value with the connection URL from above.

Note that your connection URL defined here will need to contain ?sslmode=require at the end.

DATABASE_URL=`postgresql://<YOUR_WORKSPACE_ID>:<YOUR_API_KEY>@<YOUR_REGION>.sql.xata.sh:5432/<YOUR_DATABASE_NAME>:<YOUR_BRANCH_NAME>?sslmode=require`
Enter fullscreen mode Exit fullscreen mode

Using Driver Adapters (Optional)

If you choose to use the drivers adapter you will also need to run:

npm install @prisma/adapter-pg pg

Generating the database schema

Prisma db push and db pull should work with Xata out of the box.

Note: At the time of publishing this blog post, ORM native migrations are not yet fully supported. Commands such as prisma migrate dev cannot be used with Xata Shared Clusters while prisma migrate deploy is subject to encountering errors depending on migration specifics. We recommend managing migrations natively using the Xata UI or CLI and use prisma db pull/push as shown here.

After setting your connection string, run prisma db pull. This will run introspect on your remote Xata database and write your Prisma Schema file. You will be able to use this file to subsequently manage migrations.

After running this command your schema.prisma file should look like:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
  provider        = "prisma-client-js"
  // The following line will need to be added if
  // using driver adapters.
  previewFeatures = ["driverAdapters"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
model companies_med_250 {
  address         String?
  catch_phrase    String?
  ceo             String?
  phone           String?
  email           String?
  exchange        String?
  xata_updatedat  DateTime          @default(now()) @db.Timestamptz(6)
  xata_id         String            @unique(map: "_pgroll_new_companies_med_250_xata_id_key") @default(dbgenerated("('rec_'::text || (xata_private.xid())::text)"))
  xata_version    Int               @default(0)
  xata_createdat  DateTime          @default(now()) @db.Timestamptz(6)
  prices_med_2500 prices_med_2500[]
}

/// This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
model prices_med_2500 {
  timestamp         DateTime?          @db.Timestamptz(6)
  symbol            String?
  price             Float?
  delta             Float?
  percentage        Float?
  xata_id           String             @unique(map: "_pgroll_new_prices_med_2500_xata_id_key") @default(dbgenerated("('rec_'::text || (xata_private.xid())::text)"))
  xata_version      Int                @default(0)
  xata_createdat    DateTime           @default(now()) @db.Timestamptz(6)
  xata_updatedat    DateTime           @default(now()) @db.Timestamptz(6)
  companies_med_250 companies_med_250? @relation(fields: [symbol], references: [xata_id], onUpdate: NoAction, map: "symbol_link")
}

Enter fullscreen mode Exit fullscreen mode

Generating the Client

After generating your schema. You’ll need to run npx prisma generate to get type-safety in your application code.

Running queries

Create an index.ts file at the project root with the following:

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();
async function main() {
  const record = await prisma.prices_med_2500.findMany({
    where: {
      symbol: {
        equals: 'PATT'
      }
    }
  });
  console.log('record', record);
}

main()
  .then(async () => {
    await prisma.$disconnect();
  })
  .catch(async (e) => {
    console.error(e);
    await prisma.$disconnect();
    process.exit(1);
  });
Enter fullscreen mode Exit fullscreen mode

Driver Adapters (Optional)

Client initialisation for driver adapters is slightly different:

import { Pool } from 'pg';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@prisma/client';

const connectionString = `${process.env.DATABASE_URL}`;

const pool = new Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
async function main() {
  const record = await prisma.prices_med_2500.findMany({
    where: {
      symbol: {
        equals: 'PATT'
      }
    }
  });
  console.log('record', record);
}

main()
  .then(async () => {
    await prisma.$disconnect();
  })
  .catch(async (e) => {
    console.error(e);
    await prisma.$disconnect();
    process.exit(1);
  });
Enter fullscreen mode Exit fullscreen mode

Changing the schema

You may want to add, delete, or modify your tables or fields. Changes can come from the Prisma Schema file and be pushed onto the remote database, or they can come from the remote database and be pulled into the Prisma Schema file which would update your Prisma Client types. Here is an example of how you could add a new field to your existing database schema via the Prisma Schema file and have those changes applied to your remote database.

model companies_med_250 {
  city            String? // Add a new field and a type like so.
  address         String?
  catch_phrase    String?
  ceo             String?
  phone           String?
  email           String?
  exchange        String?
  xata_updatedat  DateTime          @default(now()) @db.Timestamptz(6)
  xata_id         String            @unique(map: "_pgroll_new_companies_med_250_xata_id_key") @default(dbgenerated("('rec_'::text || (xata_private.xid())::text)"))
  xata_version    Int               @default(0)
  xata_createdat  DateTime          @default(now()) @db.Timestamptz(6)
  prices_med_2500 prices_med_2500[]
}
Enter fullscreen mode Exit fullscreen mode

After saving this file, run prisma db push. The column should be added to your remote database and your Prisma Client should be aware of the new field available on your model.

Get started

And that's it, it's that easy to connect Prisma to your Xata database. This functionality is currently only available with the public beta of our Postgres service.

Sign up today to get started! We're always around if you have any questions. Pop into Discord and say hi or reach out on X | Twitter. Happy building 🦋

Top comments (0)