feat(db-vercel-postgres): allow to use a local database using pg instead of @vercel/postgres (#9771)
### What? This PR allows you to use a local database when using `vercelPostgresAdapter`. This adapter doesn't work with them because it requires an SSL connection and Neon's WS proxy. Instead we fallback to using pool from `pg` if `hostname` is either `127.0.0.1` or `localhost`. If you still want to use `@vercel/postgres` even locally you can pass `disableUsePgForLocalDatabase: true` here and you'd have to spin up the DB with a special Neon's Docker Compose setup - https://vercel.com/docs/storage/vercel-postgres/local-development#option-2:-local-postgres-instance-with-docker ### Why? Forcing people to use a cloud database locally isn't great. Not only they are slow but also paid. --------- Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
@@ -50,6 +50,11 @@ export default buildConfig({
|
||||
})
|
||||
```
|
||||
|
||||
<Banner type="info">
|
||||
<strong>Note:</strong>
|
||||
If when using `vercelPostgresAdapter` your `process.env.POSTGRES_URL` or `pool.connectionString` points to a local database (e.g hostname has `localhost` or `127.0.0.1`) we use the `pg` module for pooling instead of `@vercel/postgres`. This is because `@vercel/postgres` doesn't work with local databases, if you want to disable that behavior, you can pass `forceUseVercelPostgres: true` to adapter's 'args and follow [Vercel guide](https://vercel.com/docs/storage/vercel-postgres/local-development#option-2:-local-postgres-instance-with-docker) for a Docker Neon DB setup.
|
||||
</Banner>
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
@@ -178,7 +183,7 @@ postgresAdapter({
|
||||
})
|
||||
```
|
||||
|
||||
Make sure Payload doesn't overlap table names with its collections. For example, if you already have a collection with slug "users", you should either change the slug or `dbName` to change the table name for this collection.
|
||||
Make sure Payload doesn't overlap table names with its collections. For example, if you already have a collection with slug "users", you should either change the slug or `dbName` to change the table name for this collection.
|
||||
|
||||
|
||||
### afterSchemaInit
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { Connect } from 'payload'
|
||||
import { pushDevSchema } from '@payloadcms/drizzle'
|
||||
import { sql, VercelPool } from '@vercel/postgres'
|
||||
import { drizzle } from 'drizzle-orm/node-postgres'
|
||||
import pg from 'pg'
|
||||
|
||||
import type { VercelPostgresAdapter } from './types.js'
|
||||
|
||||
@@ -24,10 +25,30 @@ export const connect: Connect = async function connect(
|
||||
|
||||
try {
|
||||
const logger = this.logger || false
|
||||
|
||||
let client: pg.Pool | VercelPool
|
||||
|
||||
const connectionString = this.poolOptions?.connectionString ?? process.env.POSTGRES_URL
|
||||
|
||||
// Use non-vercel postgres for local database
|
||||
if (
|
||||
!this.forceUseVercelPostgres &&
|
||||
connectionString &&
|
||||
['127.0.0.1', 'localhost'].includes(new URL(connectionString).hostname)
|
||||
) {
|
||||
client = new pg.Pool(
|
||||
this.poolOptions ?? {
|
||||
connectionString,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
client = this.poolOptions ? new VercelPool(this.poolOptions) : sql
|
||||
}
|
||||
|
||||
// Passed the poolOptions if provided,
|
||||
// else have vercel/postgres detect the connection string from the environment
|
||||
this.drizzle = drizzle({
|
||||
client: this.poolOptions ? new VercelPool(this.poolOptions) : sql,
|
||||
client,
|
||||
logger,
|
||||
schema: this.schema,
|
||||
})
|
||||
|
||||
@@ -99,6 +99,7 @@ export function vercelPostgresAdapter(args: Args = {}): DatabaseAdapterObj<Verce
|
||||
json: true,
|
||||
},
|
||||
fieldConstraints: {},
|
||||
forceUseVercelPostgres: args.forceUseVercelPostgres ?? false,
|
||||
idType: postgresIDType,
|
||||
indexes: new Set<string>(),
|
||||
initializing,
|
||||
|
||||
@@ -31,6 +31,13 @@ export type Args = {
|
||||
*/
|
||||
disableCreateDatabase?: boolean
|
||||
extensions?: string[]
|
||||
/**
|
||||
* By default, we connect to a local database using the `pg` module instead of `@vercel/postgres`.
|
||||
* This is because `@vercel/postgres` doesn't work with local databases.
|
||||
* If you still want to use `@vercel/postgres` even locally you can pass `true` here
|
||||
* and you'd to spin up the database with a special Neon's Docker Compose setup - https://vercel.com/docs/storage/vercel-postgres/local-development#option-2:-local-postgres-instance-with-docker
|
||||
*/
|
||||
forceUseVercelPostgres?: boolean
|
||||
idType?: 'serial' | 'uuid'
|
||||
localesSuffix?: string
|
||||
logger?: DrizzleConfig['logger']
|
||||
@@ -58,6 +65,7 @@ export type Args = {
|
||||
}
|
||||
|
||||
export type VercelPostgresAdapter = {
|
||||
forceUseVercelPostgres?: boolean
|
||||
pool?: VercelPool
|
||||
poolOptions?: Args['pool']
|
||||
} & BasePostgresAdapter
|
||||
|
||||
Reference in New Issue
Block a user