Files
supabase/apps/docs/content/guides/database/connecting-to-postgres.mdx

377 lines
14 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: 'connecting-to-postgres'
title: 'Connecting to your database'
description: 'Explore the options for connecting to your Postgres database.'
subtitle: 'Explore the options for connecting to your Postgres database.'
---
Supabase provides several options for programmatically connecting to your Postgres database:
1. Programmatic access using the Data APIs
1. Connection pooling for scalable connections
1. Direct connections using the built-in Postgres connection system
<Admonition type="caution">
Direct database connections will start resolving to an IPv6 address. Starting from January 26, 2024, projects will be gradually migrated to this behavior. If you connect to your database using the REST or GraphQL endpoints, this doesn't affect you. If you use the database connection string, see the GitHub discussion on [how to prepare for IPv6](https://github.com/orgs/supabase/discussions/17817).
</Admonition>
## Data APIs
Supabase provides auto-updating Data APIs. These are the easiest way to get started if you are managing data (fetching, inserting, updating). We provide several types of API to suit your preferences:
- [REST](/docs/guides/api): interact with your database through a REST interface.
- [GraphQL](/docs/guides/graphql/api): interact with your database through a GraphQL interface.
- [Realtime](/docs/guides/realtime#realtime-api): listen to database changes over websockets.
## Connection pooler
A "connection pool" is a system (external to Postgres) which manages Postgres connections.
When a client makes a request, the pooler "allocates" an available connection to the client. When the client transaction or session is completed the connection is returned to the pool and is free to be used by another client.
<figure>
<Image
className="hidden dark:block"
alt="New migration files trigger migrations on the preview instance."
src="/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works.png"
/>
<Image
className="dark:hidden"
alt="New migration files trigger migrations on the preview instance."
src="/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works--light.png"
/>
<figcaption>Connecting to the database directly vs using a Connection Pooler</figcaption>
</figure>
Every Supabase project comes with a connection pooler for managing connections to your database. The pooler provides 2 important services:
1. It manages connections for applications that connect and disconnect from the database frequently. For example, serverless functions and ORMs such as Prisma, Drizzle, and Kysely often make and drop connections to the database. If they connected directly each time, they would quickly exhaust your database server's memory. To connect to your database efficiently with such tools, you need a pooler.
2. It provides an IPv4 endpoint to connect to your database, which you can use if your network provider doesn't support IPv6. This is unlike the direct database connection, which resolves to an IPv6 address, unless you've enabled the [IPv4 add-on](https://supabase.com/docs/guides/platform/ipv4-address).
<Admonition type="tip">
The connection pooler is available in 2 modes: `Transaction` and `Session`.
</Admonition>
Transaction mode is recommended if you are connecting from serverless environments. A connection is assigned to the client for the duration of a transaction. Two consecutive transactions from the same client can be executed over two different connections. Some session-based Postgres features such as prepared statements are _not available_ with this option.
Session mode is similar to connecting to your database directly. There is full support for prepared statements in this mode. When a new client connects, a connection is assigned to the client until it disconnects. You might run into pooler connection limits since the connection is held till the client disconnects.
You can find the connection pool config in the [Database settings](/dashboard/project/_/settings/database) inside the dashboard:
1. Go to the `Settings` section.
2. Click `Database`.
3. Under `Connection string`, make sure `Use connection pooling` is checked. Copy the URI.
## Direct connections
You can also use a direct connection to connect directly to your Postgres database. By default, you can connect to it via IPv6, which isn't supported by all networks. If you need an IPv4 address, use the [connection pooler](#connection-pooler) instead or enable the [IPv4 add-on](https://supabase.com/docs/guides/platform/ipv4-address).
You can find the direct connection string in the [Database settings](https://supabase.com/dashboard/project/_/settings/database) inside the dashboard:
1. Go to the `Settings` section.
2. Click `Database`.
3. Under `Connection string`, make sure `Use connection pooling` is unchecked. Copy the URI.
## Choosing a connection method
- Are you performing operations supported by the Data APIs? We recommend using the APIs.
- Are you connecting to your database and then _disconnecting_ immediately (for example, are you running your code in a serverless environment)? Use the connection pooler in transaction mode.
- Are you on a network that doesn't support IPv6? Use the connection pooler. (If you need a long-lived connection, for example for prepared statements, use session mode.)
- Are you connecting to your database and _maintaining_ a connection, and does your network support IPv6? Use a direct connection.
## Connecting with SSL
You should connect to your database using SSL wherever possible, to prevent snooping and man-in-the-middle attacks.
You can obtain your connection info and Server root certificate from your application's dashboard:
![Connection Info and Certificate.](/docs/img/database/database-settings-ssl.png)
## Integrations
### Connecting with Drizzle
[Drizzle ORM](https://github.com/drizzle-team/drizzle-orm) is a TypeScript ORM for SQL databases designed with maximum type safety in mind. You can use their ORM to connect to your database.
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Install">
Install Drizzle and related dependencies.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```shell
npm i drizzle-orm postgres
npm i -D drizzle-kit
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Create your models">
Create a `schema.ts` file and define your models.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts schema.ts
import { pgTable, serial, text, varchar } from "drizzle-orm/pg-core";
export const users = pgTable('users', {
id: serial('id').primaryKey(),
fullName: text('full_name'),
phone: varchar('phone', { length: 256 }),
});
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Connect">
Connect to your database using the Connection Pooler.
In your [`Database Settings`](https://supabase.com/dashboard/project/_/settings/database), make sure `Use connection pooler` is checked, then copy the URI and save it as the `DATABASE_URL` environment variable. Remember to replace the password placeholder with your actual database password.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts db.ts
import 'dotenv/config'
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
const connectionString = process.env.DATABASE_URL
// Disable prefetch as it is not supported for "Transaction" pool mode
export const client = postgres(connectionString, { prepare: false })
export const db = drizzle(client);
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
### Connecting with pgAdmin
[`pgAdmin`](https://www.pgadmin.org/) is a GUI tool for managing Postgres databases. You can use it to connect to your database via SSL:
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Register">
Register a new Postgres server.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
<Image
className="hidden dark:block"
alt="Register a new postgres server."
src="/docs/img/guides/database/connecting-to-postgres/pgadmin/register-server-pgAdmin.png?v=2"
/>
<Image
className="dark:hidden"
alt="Register a new postgres server."
src="/docs/img/guides/database/connecting-to-postgres/pgadmin/register-server-pgAdmin--light.png"
/>
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Name">
Name your server.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
![Name Postgres Server.](/docs/img/guides/database/connecting-to-postgres/pgadmin/name-pg-server.png)
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Connect">
Add the connection info. Go to your [`Database Settings`](https://supabase.com/dashboard/project/_/settings/database). Make sure `Use connection pooling` is enabled. Switch the connection mode to `Session` and copy your connection parameters.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
![Add Connection Info.](/docs/img/guides/database/connecting-to-postgres/pgadmin/add-pg-server-conn-info.png)
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={4}>
<StepHikeCompact.Details title="SSL">
Navigate to the Parameters tab and select connection parameter as Root Certificate. Next navigate to the Root certificate input, it will open up a file-picker modal. Select the certificate you downloaded from your Supabase dashboard and save the server details. PgAdmin should now be able to connect to your Postgres via SSL.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
![Add Connection Info.](/docs/img/guides/database/connecting-to-postgres/pgadmin/database-settings-host.png)
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
### Connecting with psql
[`psql`](https://www.postgresql.org/docs/current/app-psql.html) is a command-line tool that comes with Postgres.
Download your [SSL certificate](#connecting-with-ssl) to `/path/to/prod-supabase.cer`.
Find your connection settings. Go to your [`Database Settings`](https://supabase.com/dashboard/project/_/settings/database) and make sure `Use connection pooling` is checked. Change the connection mode to `Session`, and copy the parameters into the connection string:
```shell
psql "sslmode=verify-full sslrootcert=/path/to/prod-supabase.cer host=[CLOUD_PROVIDER]-0-[REGION].pooler.supabase.com dbname=postgres user=postgres.[PROJECT_REF]"
```
### Connecting with Prisma
Refer to our [Prisma integration guide](https://supabase.com/partners/integrations/prisma) for more details.
### Connecting with Postgres.js
[Postgres.js](https://github.com/porsager/postgres) is a full-featured PostgreSQL client for Node.js and Deno.
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Install">
Install Postgres.js and related dependencies.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```shell
npm i postgres
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Connect">
Create a `db.js` file with the connection details.
To get your connection details, go to your [`Database Settings`](https://supabase.com/dashboard/project/_/settings/database). Make sure `Use connection pooling` is enabled. Choose `Transaction Mode` if you're on a platform with transient connections, such as a serverless function, and `Session Mode` if you have a long-lived connection. Copy the URI and save it as the environment variable `DATABASE_URL`.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts
// db.js
import postgres from 'postgres'
const connectionString = process.env.DATABASE_URL
const sql = postgres(connectionString)
export default sql
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Execute commands">
Use the connection to execute commands.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts
import sql from './db.js'
async function getUsersOver(age) {
const users = await sql`
select name, age
from users
where age > ${ age }
`
// users = Result [{ name: "Walter", age: 80 }, { name: 'Murray', age: 68 }, ...]
return users
}
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
## Troubleshooting Supavisor
Connection pooler logs are found [here](https://supabase.com/dashboard/project/_/logs/pooler-logs). The following are common errors and their solutions:
- Max client connections reached
This error happens when the number of connections to Supavisor is more than [the allowed limit of your compute add-on](https://supabase.com/docs/guides/platform/compute-add-ons). Upgrade the database to a higher compute add-on to increase the number of Supavisor connections.
- Connection failed \{:error, :eaddrnotavail} to 'db.xxx.supabase.co':5432
Supavisor cannot connect to the customer database. This is usually caused if the target database is unable to respond.
- Connection failed \{:error, :nxdomain} to 'db.xxx.supabase.co':5432
Supavisor cannot connect to the customer database. This is usually caused if the target database is unable to respond.
- Connection closed when state was authentication
This error happens when either the database doesnt exist or if the user doesn't have the right credentials.
- Subscribe error: \{:error, :worker_not_found}
This log event is emitted when the client tries to connect to the database, but Supavisor does not have the necessary information to route the connection. Try reconnecting to the database as it can take some time for the project information to propagate to Supavisor.
- Subscribe error: \{:error, \{:badrpc, \{:error, \{:erpc, :timeout}}}}
This is a timeout error when the communication between different Supavisor nodes takes longer than expected. Try reconnecting to the database.
- Terminating with reason :client_termination when state was :busy
This error happens when the client terminates the connection before the connection with the database is completed.