Schema Extension in Payload

This hook runs before the schema is built. You can use it to extend your database structure with tables that won’t be managed by Payload.

import { postgresAdapter } from '@payloadcms/db-postgres'
import { integer, pgTable, serial } from '@payloadcms/db-postgres/drizzle/pg-core'
postgresAdapter({
  beforeSchemaInit: [
    ({ schema, adapter }) => {
      return {
        ...schema,
        tables: {
          ...schema.tables,
          addedTable: pgTable('added_table', {
            id: serial('id').notNull(),
          }),
        },
     }
    },
 ],
})

One use case is preserving your existing database structure when migrating to Payload. By default, Payload drops the current database schema, which may not be desirable in this scenario.

Note for generated schema:

Columns and tables, added in schema hooks won’t be added to the generated via payload generate:db-schema Drizzle schema.

If you want them to be there, you either have to edit this file manually or mutate the internal Payload “raw” SQL schema in the beforeSchemaInit:

import { postgresAdapter } from '@payloadcms/db-postgres'
postgresAdapter({
  beforeSchemaInit: [
    ({ schema, adapter }) => {
      // Add a new table
      adapter.rawTables.myTable = {
        name: 'my_table',
        columns: {
          my_id: {
            name: 'my_id',
            type: 'serial',
            primaryKey: true
          }
        }
      }
      // Add a new column to generated by Payload table:
      adapter.rawTables.posts.columns.customColumn = {
        name: 'custom_column',
        // Note that Payload SQL doesn't support everything that Drizzle does.
        type: 'integer',
        notNull: true
      }
      // Add a new index to generated by Payload table:
      adapter.rawTables.posts.indexes.customColumnIdx = {
        name: 'custom_column_idx',
        unique: true,
        on: ['custom_column']
      }
      return schema
    },
  ],
})

Leave a comment

Your email address will not be published. Required fields are marked *