I have a problem with the following migration in KnexJS, working with PostgreSQL:
exports.up = (knex) => {
knex.raw('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"');
return knex.schema.createTable('car_brands', (table) => {
table.uuid('brandId').unique().notNullable().primary().defaultTo(knex.raw('uuid_generate_v4()'));
table.string('name').notNullable().unique();
table.timestamp('created_at').notNullable().defaultTo(knex.raw('now()'));
table.timestamp('updated_at').notNullable().defaultTo(knex.raw('now()'));
});
};
exports.down = (knex) => {
knex.raw('drop extension if exists "uuid-ossp"');
return knex.schema.dropTable('car_brands');
};
I am using the UUID
type for my default values, by using thedefaultTo(knex.raw('uuid_generate_v4()'))
.
However, when running the above migration, by:
knex migrate:latest --env development --knexfile knexfile.js --debug true
I get an error that:
function uuid_generate_v4() does not exist
Do you know why the knex.raw()
query method is not working?
The problem is you are running
knex.raw('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"');
and
knex.schema.createTable('car_brands');
asynchronously, so the first query is not executed before the second one.
Rewrite it using async/await
:
exports.up = async (knex) => {
await knex.raw('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"');
return knex.schema.createTable('car_brands', (table) => {
table.uuid('brandId').unique().notNullable().primary().defaultTo(knex.raw('uuid_generate_v4()'));
table.string('name').notNullable().unique();
table.timestamp('created_at').notNullable().defaultTo(knex.raw('now()'));
table.timestamp('updated_at').notNullable().defaultTo(knex.raw('now()'));
});
};
or using Promises
:
exports.up = (knex) => {
knex.raw('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"')
.then(() => {
return knex.schema.createTable('car_brands', (table) => {
table.uuid('brandId').unique().notNullable().primary().defaultTo(knex.raw('uuid_generate_v4()'));
table.string('name').notNullable().unique();
table.timestamp('created_at').notNullable().defaultTo(knex.raw('now()'));
table.timestamp('updated_at').notNullable().defaultTo(knex.raw('now()'));
});
})
};
These are the steps I took to resolve this issue in my app with PostgreSQL, Objection and KNEX.
Go to your database to verify your extension is available.
postgres=# SELECT * FROM pg_extension;
Verify "uuid-ossp" is installed in the database_name you need.
database_name=# CREATE EXTENSION "uuid-ossp"
Back to your app, go to the KNEX migration file where you are altering your table.
t.uuid('user_id').defaultTo(knex.raw('uuid_generate_v4()'));
Use the KNEX command to get the Batch running:
knex migrate:latest
Insert a new raw in your table and verify your UUID has been auto-generated.
I hope these steps can be helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With