node-pg-migrate
node-pg-migrate copied to clipboard
Feature: Support plain json objects for jsonb defaults.
it should be possible to specify a jsonb fields default value as a plain js object.
Error
CREATE TABLE "my_table" (
"id" serial PRIMARY KEY,
"my_column" jsonb DEFAULT NOT NULL
^^^^
);
Migrations failed error: syntax error at or near "NOT"
at Parser.parseErrorMessage (/Data/Projects/Infrastructure/azure-archiver/node_modules/pg-protocol/src/parser.ts:357:11)
at Parser.handlePacket (/Data/Projects/Infrastructure/azure-archiver/node_modules/pg-protocol/src/parser.ts:186:21)
at Parser.parse (/Data/Projects/Infrastructure/azure-archiver/node_modules/pg-protocol/src/parser.ts:101:30)
at Socket.<anonymous> (/Data/Projects/Infrastructure/azure-archiver/node_modules/pg-protocol/src/index.ts:7:48)
Code
// this is ideal
pgm.addColumn('my_table', 'my_column', {
type: 'jsonb',
notNull: true,
default: { attempts: 0, uploads: 0 }
});
// this is whats required:
pgm.addColumn('my_table', 'my_column', {
type: 'jsonb',
notNull: true,
default: pgm.func(`'{ "attempts": 0, "uploads": 0 }'::jsonb`)
});
Suggestion
a naive psuedo-implementation
const JSON_FIELDS = ['json', 'jsonb];
if (column.notNull
&& column.default != null
&& JSON_FIELDS.includes(column.type)
) {
if (!lodash.isplainobject(column.default)) {
throw new Error(`${column.type} defaults can only be plain objects`);
}
const defaultStatement = `'${JSON.serialize(column.default)}'::${column.type}`
}
Hello Rijnhard,
Thank you for your suggestion. We will consider adding this feature to one of the next releases.
However please note that there is a quite comfortable workaround as you yourself wrote, so this feature will probably not be the top-priority.