我使用knex和MySql。这是我的迁移文件:
const { onUpdateTrigger } = require('../../../../knexfile')
const { onInsertTrigger } = require('../../../../knexfile')
exports.up = function (knex, Promise) {
return knex.schema.createTable('users', (table) => {
console.info("------> Creating table");
table.increments('id').unsigned().primary();
table.string('username').unique().notNullable();
table.string('password').notNullable();
table.timestamp('modified').notNullable();
table.timestamp('created').notNullable().defaultTo(knex.raw('NOW()'));
}).then(function () {
console.info("------> Creating trigger");
knex.raw(onUpdateTrigger('users'));
knex.raw(onInsertTrigger('users'));
});
};
exports.down = function (knex, Promise) {
return knex.schema.dropTable('users');
};
knexfile.js如下:
...
development: {
client: 'mysql',
connection: {
host: 'localhost',
user: 'pbrause',
password: '********',
database: 'mydb',
charset: 'utf8',
multipleStatements : true
},
debug: true,
migrations: {
directory: __dirname + '/src/server/db/migrations'
},
seeds: {
directory: __dirname + '/src/server/db/seeds'
}
},
...
onInsertTrigger: function(table) {
`DELIMITER $$
CREATE TRIGGER \`mydatabase\`.\`${table}_BEFORE_INSERT\`
BEFORE INSERT ON \`${table}\`
FOR EACH ROW
BEGIN
SET new.modified = NOW();
END$$
DELIMITER ;`
},
onUpdateTrigger: function(table) {
`DELIMITER $$
CREATE TRIGGER \`mydatabase\`.\`${table}_BEFORE_UPDATE\`
BEFORE UPDATE ON \`${table}\`
FOR EACH ROW
BEGIN
SET new.modified = NOW();
END$$
DELIMITER ;`
}
...
我尝试了两种变体 - 一种是SQL代码在knex.raw(...)
语句中,以及您在上面看到的方式。在这两种情况下都不会创建触发器,并且knex调试输出告诉我这些“原始”语句不会被执行。在这两种情况下都能正确创建表。
知道为什么这不起作用?
答案 0 :(得分:1)
首先,你要调用knex.raw()
并行,而不必等待它们的执行完成:
}).then(function () {
console.info("------> Creating trigger");
knex.raw(onUpdateTrigger('users'));
knex.raw(onInsertTrigger('users'));
});
从那时起应该使用knex.schema.raw
或返回承诺:
}).then(function () {
console.info("------> Creating on update trigger");
return knex.raw(onUpdateTrigger('users'));
}).then(function () {
console.info("------> Creating on insert trigger");
return knex.raw(onInsertTrigger('users'));
});
或
return knex.schema.createTable('users', (table) => {
console.info("------> Creating table");
table.increments('id').unsigned().primary();
table.string('username').unique().notNullable();
table.string('password').notNullable();
table.timestamp('modified').notNullable();
table.timestamp('created').notNullable().defaultTo(knex.raw('NOW()'));
})
.raw(onUpdateTrigger('users'))
.raw(onInsertTrigger('users'));
另一个问题可能是knex.raw()
(实际上db驱动程序不允许它正常)不支持默认将多个SQL语句作为单个查询发送到DB。
如果您使用的是mysql,可以通过为驱动程序https://github.com/mysqljs/mysql#connection-options设置multipleStatements : true
配置选项来启用对它的支持。
编辑(真正回答为什么没有运行那些knex原始查询):
以上所有情况都属实,如果您以我建议的方式更改了代码,那么它已经解决了您的问题。
这些knex.raw()
查询未运行的原因是因为您只构建查询,但从不执行它们(它们不会从promise中返回,它会自动触发查询,也不会调用{{ 1}}用于那些将查询显式发送到数据库的查询。
.then()