我认为从最初的数据库交互开始使用迁移是个好主意,因此我想为数据库创建创建一个迁移。
knexfile.js
'use strict';
require('dotenv').config({ path: 'process.env' });
const config = {
client: 'pg',
connection: {
host: process.env.DB_URL,
},
};
module.exports = config;
迁移文件:
'use strict';
exports.up = function(knex, Promise) {
return knex.raw('CREATE DATABASE asd');
};
exports.down = function(knex, Promise) {
return knex.raw('DROP DATABASE asd');
};
exports.config = {
transaction: false
};
到目前为止它可以正常工作,但是当我将database
添加到knexfile配置时,它无法迁移,因为Knex尝试连接到非现有数据库。
我还尝试使用新的Knex实例进行此单一迁移,例如:
exports.up = function(_, Promise) {
// Remove database from config so Knex won't try to connect
// to a non existing database.
const config = require(process.cwd() + '/knexfile');
config.connection.database = null;
const knex = require('knex')(config);
return knex.raw('CREATE DATABASE asd');
};
但是knex在迁移之前已经初始化了,所以它失败并出现同样的错误:
error: database "asd" does not exist
有关如何从Knex迁移创建数据库的任何想法?我对任何有关数据库创建的最佳实践持开放态度,可以处理不同环境的数据库URL。
答案 0 :(得分:3)
Knex并不真正支持轻松创建数据库。
首先,运行迁移必须创建表,其中包含已运行的迁移的信息,因此数据库必须在执行迁移之前存在。
通常您希望有不同的配置文件来创建数据库,用户具有足够的权限来创建数据库并且连接到例如数据库。名为postgres
或template1
的数据库。
就像您应该只需创建简单的脚本一样,这样可以确保在运行迁移之前创建数据库。
还有工具knex-db-manager
(主要由我编写)可能有助于创建数据库所有者用户/数据库的任务。
答案 1 :(得分:1)
我已经添加了一个postinstall
脚本来运行这样的脚本:
'use strict';
async function createDatabase() {
const config = require(process.cwd() + '/knexfile');
config.connection.database = null;
const knex = require('knex')(config);
await knex.raw('CREATE DATABASE asd');
await knex.destroy();
}
createDatabase();
这种方式我没有将此步骤存储为迁移,但我并没有真正看到一个用户希望删除整个数据库的用例。
您如何看待这种方法?
答案 2 :(得分:0)
因为数据库是事先未知的,所以最简单的方法是使用迁移 API 创建您自己的脚本。应该可以动态指定您的数据库名称
另存为 migrate.js
const Knex = require('knex')
// You can dynamically pass the database name
// as a command-line argument, or obtain it from
// a .env file
const databaseName = 'database_name'
const connection = {
host: 'localhost',
user: 'root',
password: 'password'
}
async function main() {
let knex = Knex({
client: 'mysql',
connection
})
// Lets create our database if it does not exist
await knex.raw('CREATE DATABASE IF NOT EXISTS ??', databaseName)
// Now that our database is known, let's create another knex object
// with database name specified so that we can run our migrations
knex = Knex({
client: 'mysql',
connection: {
...connection,
database: databaseName,
}
})
// Now we can happily run our migrations
await knex.migrate.latest()
// Done!!
}
main().catch(console.log).then(process.exit)
您现在可以运行您的脚本
node migrate.js
您可以使用 .env
文件来存储您的配置或将它们作为命令行参数传递