fix(db-postgres): postgres dev push schemas

This commit is contained in:
Dan Ribbens
2024-03-08 17:05:10 -05:00
parent 95688c7e30
commit 5e385fa33b
3 changed files with 92 additions and 71 deletions

View File

@@ -1,14 +1,14 @@
import type { Payload } from 'payload'
import type { Connect } from 'payload/database'
import { eq, sql } from 'drizzle-orm'
import { sql } from 'drizzle-orm'
import { drizzle } from 'drizzle-orm/node-postgres'
import { numeric, timestamp, varchar } from 'drizzle-orm/pg-core'
import pg from 'pg'
import prompts from 'prompts'
import type { PostgresAdapter } from './types.js'
import { pushDevSchema } from './utilities/pushDevSchema.js'
const connectWithReconnect = async function ({
adapter,
payload,
@@ -93,70 +93,5 @@ export const connect: Connect = async function connect(
)
return
const { pushSchema } = await import('drizzle-kit/payload')
// This will prompt if clarifications are needed for Drizzle to push new schema
const { apply, hasDataLoss, statementsToExecute, warnings } = await pushSchema(
this.schema,
this.drizzle,
)
if (warnings.length) {
let message = `Warnings detected during schema push: \n\n${warnings.join('\n')}\n\n`
if (hasDataLoss) {
message += `DATA LOSS WARNING: Possible data loss detected if schema is pushed.\n\n`
}
message += `Accept warnings and push schema to database?`
const { confirm: acceptWarnings } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message,
},
{
onCancel: () => {
process.exit(0)
},
},
)
// Exit if user does not accept warnings.
// Q: Is this the right type of exit for this interaction?
if (!acceptWarnings) {
process.exit(0)
}
}
await apply()
// Migration table def in order to use query using drizzle
const migrationsSchema = this.pgSchema.table('payload_migrations', {
name: varchar('name'),
batch: numeric('batch'),
created_at: timestamp('created_at'),
updated_at: timestamp('updated_at'),
})
const devPush = await this.drizzle
.select()
.from(migrationsSchema)
.where(eq(migrationsSchema.batch, '-1'))
if (!devPush.length) {
await this.drizzle.insert(migrationsSchema).values({
name: 'dev',
batch: '-1',
})
} else {
await this.drizzle
.update(migrationsSchema)
.set({
updated_at: new Date(),
})
.where(eq(migrationsSchema.batch, '-1'))
}
await pushDevSchema(this)
}

View File

@@ -2,7 +2,13 @@ import type { Destroy } from 'payload/database'
import type { PostgresAdapter } from './types.js'
import { pushDevSchema } from './utilities/pushDevSchema.js'
export const destroy: Destroy = async function destroy(this: PostgresAdapter) {
// TODO: this hangs test suite for some reason
// await this.pool.end()
if (process.env.NODE_ENV !== 'production') {
await pushDevSchema(this)
} else {
// TODO: this hangs test suite for some reason
// await this.pool.end()
}
}

View File

@@ -0,0 +1,80 @@
import { eq } from 'drizzle-orm'
import { numeric, timestamp, varchar } from 'drizzle-orm/pg-core'
import prompts from 'prompts'
import type { PostgresAdapter } from '../types.js'
const { pushSchema } = await import('drizzle-kit/payload')
/**
* Pushes the development schema to the database using Drizzle.
*
* @param {PostgresAdapter} db - The PostgresAdapter instance connected to the database.
* @returns {Promise<void>} - A promise that resolves once the schema push is complete.
*/
export const pushDevSchema = async (db: PostgresAdapter) => {
// This will prompt if clarifications are needed for Drizzle to push new schema
const { apply, hasDataLoss, statementsToExecute, warnings } = await pushSchema(
db.schema,
db.drizzle,
)
if (warnings.length) {
let message = `Warnings detected during schema push: \n\n${warnings.join('\n')}\n\n`
if (hasDataLoss) {
message += `DATA LOSS WARNING: Possible data loss detected if schema is pushed.\n\n`
}
message += `Accept warnings and push schema to database?`
const { confirm: acceptWarnings } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message,
},
{
onCancel: () => {
process.exit(0)
},
},
)
// Exit if user does not accept warnings.
// Q: Is this the right type of exit for this interaction?
if (!acceptWarnings) {
process.exit(0)
}
}
await apply()
// Migration table def in order to use query using drizzle
const migrationsSchema = db.pgSchema.table('payload_migrations', {
name: varchar('name'),
batch: numeric('batch'),
created_at: timestamp('created_at'),
updated_at: timestamp('updated_at'),
})
const devPush = await db.drizzle
.select()
.from(migrationsSchema)
.where(eq(migrationsSchema.batch, '-1'))
if (!devPush.length) {
await db.drizzle.insert(migrationsSchema).values({
name: 'dev',
batch: '-1',
})
} else {
await db.drizzle
.update(migrationsSchema)
.set({
updated_at: new Date(),
})
.where(eq(migrationsSchema.batch, '-1'))
}
}