迁移中的 KnexJS 原始查询

KnexJS raw query in migration

我在 KnexJS 中使用 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');
};

我使用 UUID 类型作为默认值,方法是使用
defaultTo(knex.raw('uuid_generate_v4()')).

但是,当运行以上迁移时,通过:

knex migrate:latest --env development --knexfile knexfile.js --debug true

我得到一个错误:

function uuid_generate_v4() does not exist

你知道为什么 knex.raw() 查询方法不起作用吗?

问题是你运行

knex.raw('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"');

knex.schema.createTable('car_brands');

异步,所以第一个查询不会在第二个查询之前执行。

使用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()'));
    });
};

或使用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()'));
            });
        })
};

这些是我使用 PostgreSQL、Objection 和 KNEX 在我的应用程序中解决此问题所采取的步骤。

  1. 转到您的数据库以验证您的扩展是否可用。

    postgres=# SELECT * FROM pg_extension;
    
  2. 验证 "uuid-ossp" 已安装在您需要的 database_name 中。

    database_name=# CREATE EXTENSION "uuid-ossp"
    
  3. 返回您的应用程序,转到您要更改 table 的 KNEX 迁移文件。

    t.uuid('user_id').defaultTo(knex.raw('uuid_generate_v4()'));
    
  4. 使用KNEX命令获取Batch运行:

    knex migrate:latest
    
  5. 在您的 table 中插入一个新的原始文件并验证您的 UUID 是否已自动生成。

希望这些步骤对您有所帮助。