Skip to content

Column Operations ​

Column Definitions ​

The createTable and addColumns methods both take a columns argument that specifies column names and options. It is an object (key/value) where each key is the name of the column, and the value is another object that defines the options for the column.

OptionTypeDescription
typestringData type (use normal postgres types)
arrayboolean or numberDefines the column as a PostgreSQL array type. Use true for ARRAY or a number for ARRAY[n].
collationstringCollation of data type
uniquebooleanSet to true to add a unique constraint on this column
primaryKeybooleanSet to true to make this column the primary key
notNullbooleanSet to true to make this column not null
defaultValueAdds DEFAULT clause for column. See Default values
checkstring or functionSQL for a check constraint, or a callback receiving the quoted column identifier
referencesReferenceTarget table, optionally with explicit column names
referencesConstraintNamestringName of the created constraint
referencesConstraintCommentstringComment on the created constraint
onDeletestringAdds ON DELETE constraint for a reference column
onUpdatestringAdds ON UPDATE constraint for a reference column
matchstringFULL or SIMPLE
deferrablebooleanFlag for deferrable column constraint
deferredbooleanFlag for initially deferred deferrable column constraint
commentstringAdds comment on column
expressionGeneratedstringExpression to compute column value
sequenceGeneratedobjectCreates identity column see sequence options section
precedencestringALWAYS or BY DEFAULT

To reference a unique column other than the primary key, specify its name:

javascript
pgm.addColumns('orders', {
  customer_code: {
    type: 'text',
    references: { schema: 'app', name: 'customers', columns: 'code' },
  },
});

A column-level foreign key must target a single column. Specify an explicit target with a string or a one-element array in references.columns. For composite foreign keys, use the constraint definition.

Default values ​

The default option of column definitions, alterColumn, createDomain and alterDomain accepts:

ValueExampleRendered SQL
numberdefault: 0DEFAULT 0
booleandefault: falseDEFAULT false
stringdefault: 'draft'DEFAULT $pga$draft$pga$
arraydefault: ['a', 'b'] (on text[])DEFAULT ARRAY[$pga$a$pga$,$pga$b$pga$]
plain JSON objectdefault: { attempts: 0 } (on jsonb)DEFAULT $pga${"attempts":0}$pga$
pgm.func()default: pgm.func('now()') (on timestamptz)DEFAULT now()
nulldefault: nullsee below

A string is always escaped as a string literal, so default: 'now()' stores the text now(). Use pgm.func() for SQL expressions and function calls.

null and an omitted default behave differently depending on the operation:

  • createTable, addColumns and createDomain: default: null adds DEFAULT NULL. Omitting default adds no DEFAULT clause.
  • alterColumn and alterDomain: default: null removes the existing default with DROP DEFAULT. Omitting default leaves the existing default unchanged.

JSON defaults ​

Plain objects containing JSON values can be used as defaults for json and jsonb columns in createTable, addColumns (or addColumn), and alterColumn:

javascript
pgm.addColumns('uploads', {
  stats: {
    type: 'jsonb',
    notNull: true,
    default: { attempts: 0, uploads: 0 },
  },
});

pgm.alterColumn('uploads', 'stats', { default: { attempts: 1, uploads: 0 } });

Objects are serialized with JSON.stringify and escaped as SQL strings; PostgreSQL converts them to the destination type. Nested objects and arrays are JSON data. The same support applies to domain defaults, function argument defaults, and view column defaults. The DefaultValue type accepts objects declared with either a TypeScript interface or a type alias; the plain-object check and JSON serialization happen at runtime. Nested Date values use their toJSON method and become ISO strings, just as with JSON.stringify.

Top-level arrays still produce PostgreSQL arrays. For a JSON array default, use default: JSON.stringify([1, 2]). Strings that already contain JSON, such as default: '{}', and SQL expressions made with pgm.func(...) continue to work. Objects with literal: true retain their existing meaning as raw SQL literals; to store such an object as JSON, pass JSON.stringify(object) instead.

Use JSON-compatible values: circular references and BigInt cause serialization to throw before the operation is queued. A top-level class instance such as a Date, Map, or Set, or a function, throws a TypeError instead of generating invalid SQL. Explicit SQL literals remain supported.

Reusable check constraints ​

Use a check callback when a type shorthand needs to refer to the column it is applied to:

javascript
export const shorthands = {
  price: { type: 'numeric', check: (column) => `${column} > 0` },
};

export const up = (pgm) => {
  pgm.createTable('products', { retail_price: 'price' });
  pgm.addColumns('products', { wholesale_price: 'price' });
};

This generates CHECK ("retail_price" > 0) and CHECK ("wholesale_price" > 0). The callback receives the column identifier already quoted and, when enabled, decamelized. Interpolate it directly without adding quotes. Return a synchronous SQL expression without the CHECK wrapper; the returned SQL is used as written. Empty or whitespace-only strings and non-string results (including promises) throw a TypeError before SQL is queued. Callbacks also work in ordinary column definitions. A column's explicit check overrides the shorthand's check. Existing string checks remain literal SQL.

Data types & Convenience Shorthand ​

Data type strings will be passed through directly to postgres, so write types as you would if you were writing the queries by hand.

PostgreSQL array columns can be defined with the array option:

ts
pgm.addColumns('myTable', {
  tags: { type: PgType.TEXT, array: true },
  payByQuarter: { type: PgType.INTEGER, array: 4 },
});

String-based PostgreSQL array type declarations continue to work as before:

ts
pgm.addColumns('myTable', { tags: { type: 'text[]' } });

There are some aliases on types to make things more foolproof: (int, string, float, double, datetime, bool)

There is a shorthand to pass only the type instead of an option object:

ts
pgm.addColumns('myTable', { age: 'integer' });

Equivalent to:

ts
pgm.addColumns('myTable', { age: { type: 'integer' } });

There is a shorthand for normal auto-increment IDs:

ts
pgm.addColumns('myTable', { id: 'id' });

Equivalent to:

ts
pgm.addColumns('myTable', { id: { type: 'serial', primaryKey: true } });

Methods ​

Operation: addColumns ​

pgm.addColumns( tablename, new_columns, options ) ​

IMPORTANT

Add columns to an existing table - postgres docs

Alias: addColumn

Arguments ​

NameTypeDescription
tablenameNameName of the table to alter
new_columnsobjectColumn names / options -- see column definitions section
optionsobjectCheck below for available options
Options ​
OptionTypeDescription
ifNotExistsbooleanAdds column only if it does not exist

Reverse Operation: dropColumns ​

pgm.dropColumns( tablename, columns, options ) ​

IMPORTANT

Drop columns from a table - postgres docs

Alias: dropColumn

Arguments ​

NameTypeDescription
tablenameNameName of the table to alter
columnsarray of strings or objectColumns to drop (if objected, uses keys)
optionsobjectCheck below for available options
Options ​
OptionTypeDescription
ifExistsbooleanDrops column only if it exists
cascadebooleanDrop also dependent objects

Operation: renameColumn ​

pgm.renameColumn( tablename, old_column_name, new_column_name ) ​

IMPORTANT

Rename a column - postgres docs

Reverse Operation: same operation in opposite direction

Arguments ​

NameTypeDescription
tablenameNameName of the table
old_column_namestringCurrent column name
new_column_namestringNew column name

Operation: alterColumn ​

pgm.alterColumn( tablename, column_name, column_options ) ​

IMPORTANT

Alter a column (default value, type, allow null) - postgres docs

Arguments ​

NameTypeDescription
tablenameNameName of the table
column_namestringColumn to alter
column_optionsobjectOptional new column options
Column Options ​
OptionTypeDescription
defaultValueSets the default. null drops it, omitting it keeps it. See Default values
typestringNew datatype
notNullbooleanSets NOT NULL if true; drops it if false
allowNullbooleanDrops NOT NULL if true; false is ignored and warns unless notNull: true
usingstringAdds USING clause to change values in column
collationstringAdds COLLATE clause to change values in column
commentstringAdds comment on column
sequenceGeneratedobject or null or falseSets or drops identity column

Use notNull: true to disallow null values, and notNull: false or allowNull: true to allow them. Omitting both options leaves nullability unchanged. allowNull: false does not set NOT NULL and emits a warning unless notNull: true is also supplied. If both options are true or both are false, a warning explains that notNull takes precedence: true sets NOT NULL, and false drops it.

sequenceGenerated Options ​

See sequence options section, You can also set precedence to ALWAYS or BY DEFAULT.