当我执行knex.js迁移时,除了下面'recipe-ingredient'连接表中的两个外键表外,所有内容都会构建。有谁看到我做错了什么?这是迁移中的第三个表:
exports.up = function(knex, Promise) {
return Promise.all([
knex.schema.hasTable('recipe').then((exists) => {
console.log('does knex have recipe table?', exists);
if (!exists) {
return knex.schema.createTable('recipe', (table) => {
table.uuid('id');
table.string('name');
table.string('description');
})
}
}),
knex.schema.hasTable('ingredient').then((exists) => {
console.log('does knex have ingredient table?', exists);
if (!exists) {
return knex.schema.createTable('ingredient', (table) => {
table.uuid('id');
table.string('name');
})
}
}),
knex.schema.hasTable(`recipe-ingredient`).then((exists) => {
console.log('does knex have recipe-ingredient table?', exists);
if (!exists) {
return knex.schema.createTable(`recipe-ingredient`, (table)=> {
table.uuid('recipe_id').references('id').inTable('recipe').notNull();
table.uuid('ingredient_id').references('id').inTable('ingredient').notNull();
table.string('qty'); // <-- chose string instead of int because receipes include qty such as '1/3 cup', '1 teaspoon', etc.
})
}
})
])
};
exports.down = function(knex, Promise) {
return Promise.all([
knex.schema.dropTable('recipe-ingredient'),
knex.schema.dropTable('ingredient'),
knex.schema.dropTable('recipe')
])
};
这是我的knexfile.js:
require('dotenv').config();
module.exports = {
development: {
client: 'mysql',
connection: {
host: process.env.DATABASE_HOST_DEV || '127.0.0.1',
user: process.env.DATABASE_USER_DEV,
password: process.env.DATABASE_PASSWORD_DEV,
database: process.env.DATABASE_NAME_DEV
},
migrations: {
directory: __dirname+'/database/migrations'
}
},
staging: {
client: 'mysql',
connection: {
host: '127.0.0.1',
user: 'root',
password: 'password',
database: 'recipes'
},
pool: {
min: 2,
max: 10
},
migrations: {
directory: __dirname+'/database/migrations'
}
},
production: {
client: 'mysql',
connection: {
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME
},
pool: {
min: 2,
max: 10
},
migrations: {
directory: __dirname+'/database/migrations'
}
}
};
请注意,.env文件中的变量没什么特别之处。只是基本的用户名,密码和数据库名称。
答案 0 :(得分:1)
您不应使用promise.all并并行运行所有查询。
IIRC knex为这些查询创建事务,但是实际上mysql在第一个CREATE TABLE
语句之后执行隐式提交,因此事务将被提交,其余表创建可能以多种方式失败。
Knex可能会说它无法对已提交的事务执行更多查询,或者可能会忽略其他查询,或者无论如何都可以在事务外部(但通过相同的数据库连接)运行这些查询。很难说运行该迁移时会发生什么,但是绝对不能完全满足您的期望。
这应该更好地工作:
exports.up = function(knex, Promise) {
return knex.schema.hasTable('recipe').then((exists) => {
console.log('does knex have recipe table?', exists);
if (!exists) {
return knex.schema.createTable('recipe', (table) => {
table.uuid('id');
table.string('name');
table.string('description');
});
}
}).then(() => {
return knex.schema.hasTable('ingredient').then((exists) => {
console.log('does knex have ingredient table?', exists);
if (!exists) {
return knex.schema.createTable('ingredient', (table) => {
table.uuid('id');
table.string('name');
})
}
});
}).then(() => {
return knex.schema.hasTable(`recipe-ingredient`).then((exists) => {
console.log('does knex have recipe-ingredient table?', exists);
if (!exists) {
return knex.schema.createTable(`recipe-ingredient`, (table)=> {
table.uuid('recipe_id').references('id').inTable('recipe').notNull();
table.uuid('ingredient_id').references('id').inTable('ingredient').notNull();
table.string('qty'); // <-- chose string instead of int because receipes include qty such as '1/3 cup', '1 teaspoon', etc.
})
}
})
});
};
exports.down = function(knex, Promise) {
return knex.schema.dropTable('recipe-ingredient')
.then(() => knex.schema.dropTable('ingredient'))
.then(() => knex.schema.dropTable('recipe'));
};