Knex 无法 运行 迁移,因为缺少必需的配置选项 "client"
Knex cannot run migrations because required configuration option "client" is missing
我正在评估 Node.js 14.x
的新项目。我正在测试 Knex.js
和 Objection.js
与数据库交互,因此我正在构建一个概念验证项目,但我 运行 在尝试 运行 迁移(使用 npx knex --esm migrate:latest
):
[x08486@uplink:~/Workshop/Development/node-express]$ npx knex --esm migrate:latest
Error: knex: Required configuration option 'client' is missing.
at new Client (/home/x08486/Workshop/Development/node-express/node_modules/knex/lib/client.js:54:11)
at Knex (/home/x08486/Workshop/Development/node-express/node_modules/knex/lib/knex.js:14:28)
at initKnex (/home/x08486/Workshop/Development/node-express/node_modules/knex/bin/cli.js:56:10)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async Command.<anonymous> (/home/x08486/Workshop/Development/node-express/node_modules/knex/bin/cli.js:170:26)
我可以推断确实 knex
客户端可能丢失了,但我不太明白,因为它是在 knexfile.js
中导入的。我怀疑这可能与我使用 ES6 的事实有关,但不完全确定。
这是我的 package.json
文件的(节选):
{
"type": "module",
"scripts": {
"start": "node src/main.js"
},
"dependencies": {
"dotenv": "8.2.0",
"express": "4.17.1",
"knex": "0.21.18",
"objection": "2.2.14",
"sqlite3": "5.0.2"
},
"engines": {
"node": "14.x"
},
}
...然后是 knexfile.js
(也在项目的根目录):
import dotenv from "dotenv";
import knex from "knex";
import path from "path";
dotenv.config();
const config = {
// ...there are some more, but I'm using "sandbox" via dotenv
sandbox: {
client: "sqlite3",
connection: {
filename: "./sandbox.sqlite3", // ...or ":memory:"
},
debug: true,
migrations: {
directory: path.join(__dirname, "migrations"),
tableName: "knex_schema_history",
},
seeds: {
directory: path.join(__dirname, "seeds", "sandbox"),
},
useNullAsDefault: true,
},
};
const database = knex(config[process.env.NODE_ENV]);
export { database };
最后 migrations/
子目录(在项目的根目录)包含以下内容:
// 20210302134908_init.js
export function down(knex) {
return Promise.all([knex.schema.dropTable("customers")]);
}
export function up(knex) {
return Promise.all([
knex.schema.createTable("customers", function (table) {
// https://knexjs.org/#Schema-Building
table.uuid("id").notNullable().primary();
table.string("first_name", 50).notNullable();
table.string("last_name", 50).notNullable();
table.string("email", 100).index().notNullable();
// table.timestamp("created_at").defaultTo(knex.fn.now());
// table.timestamp("updated_at").defaultTo(knex.fn.now());
table.timestamps(false, true);
}),
]);
}
有什么线索吗?
来回几个小时后,它通过以这种方式更改 knexfile.js
来工作:
import dotenv from "dotenv";
import path from "path";
dotenv.config();
const config = {
// ...configurations as usual for any database/profile
};
export default config; // MUST be the default export!!!
[x80486@uplink:~/Workshop/Development/node-express]$ npx knex --esm migrate:latest
Using environment: sandbox
[
{
sql: "select * from sqlite_master where type = 'table' and name = ?",
output: [Function: output],
bindings: [ 'knex_schema_history' ]
}
]
...
[
{
sql: 'create table `customers` (`id` char(36) not null, `first_name` varchar(50) not null, `last_name` varchar(50) not null, `email` varchar(100) not null, `created_at` datetime not null default CURRENT_TIMESTAMP, `updated_at` datetime not null default CURRENT_TIMESTAMP, primary key (`id`))',
bindings: []
},
{
sql: 'create index `customers_email_index` on `customers` (`email`)',
bindings: []
}
]
{
method: 'insert',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ 1, 2021-03-03T01:04:00.988Z, '20210302134908_init.js' ],
__knexQueryUid: 'lO1x3i-L3FBDofzFXN8tB',
sql: 'insert into `knex_schema_history` (`batch`, `migration_time`, `name`) values (?, ?, ?)'
}
{
method: 'update',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ 0 ],
__knexQueryUid: '1PDbw3WTPPukvhtfjxWYt',
sql: 'update `knex_schema_history_lock` set `is_locked` = ?'
}
Batch 1 run: 1 migrations
以防万一您使用的是打字稿并且遇到类似的挑战。我在创建迁移文件时遇到了挑战:knex migrate:make create_users_table -x ts
。对 OP 的回答稍作调整对我有所帮助。
//knexfile.ts same directory as .env
import type { Knex } from "knex";
//I didn't import dotenv. it was already imported in src/config/index.
//and my knex instance has been set to use `development` as
//env
import envVariables from "./src/config/index";
const {dbClient, dbUser, dbPassword, dbDatabase, dbDatabaseTest} =
envVariables;
const config: { [key: string]: Knex.Config } = {
//Config as usual...
}
export default config;
//src/config/index
import 'dotenv/config';
export default {
port: process.env.APP_PORT,
appName: process.env.APP_NAME,
appEnv: process.env.APP_ENV || "development",
appKey: process.env.APP_KEY,
appUrl: process.env.APP_URL,
dbClient: process.env.DB_CLIENT,
dbUser: process.env.DB_USER,
dbPassword: process.env.DB_PASSWORD,
dbDatabase: process.env.DB_DATABASE,
dbDatabaseTest: process.env.DB_DATABASE_TEST,
};
我正在评估 Node.js 14.x
的新项目。我正在测试 Knex.js
和 Objection.js
与数据库交互,因此我正在构建一个概念验证项目,但我 运行 在尝试 运行 迁移(使用 npx knex --esm migrate:latest
):
[x08486@uplink:~/Workshop/Development/node-express]$ npx knex --esm migrate:latest
Error: knex: Required configuration option 'client' is missing.
at new Client (/home/x08486/Workshop/Development/node-express/node_modules/knex/lib/client.js:54:11)
at Knex (/home/x08486/Workshop/Development/node-express/node_modules/knex/lib/knex.js:14:28)
at initKnex (/home/x08486/Workshop/Development/node-express/node_modules/knex/bin/cli.js:56:10)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async Command.<anonymous> (/home/x08486/Workshop/Development/node-express/node_modules/knex/bin/cli.js:170:26)
我可以推断确实 knex
客户端可能丢失了,但我不太明白,因为它是在 knexfile.js
中导入的。我怀疑这可能与我使用 ES6 的事实有关,但不完全确定。
这是我的 package.json
文件的(节选):
{
"type": "module",
"scripts": {
"start": "node src/main.js"
},
"dependencies": {
"dotenv": "8.2.0",
"express": "4.17.1",
"knex": "0.21.18",
"objection": "2.2.14",
"sqlite3": "5.0.2"
},
"engines": {
"node": "14.x"
},
}
...然后是 knexfile.js
(也在项目的根目录):
import dotenv from "dotenv";
import knex from "knex";
import path from "path";
dotenv.config();
const config = {
// ...there are some more, but I'm using "sandbox" via dotenv
sandbox: {
client: "sqlite3",
connection: {
filename: "./sandbox.sqlite3", // ...or ":memory:"
},
debug: true,
migrations: {
directory: path.join(__dirname, "migrations"),
tableName: "knex_schema_history",
},
seeds: {
directory: path.join(__dirname, "seeds", "sandbox"),
},
useNullAsDefault: true,
},
};
const database = knex(config[process.env.NODE_ENV]);
export { database };
最后 migrations/
子目录(在项目的根目录)包含以下内容:
// 20210302134908_init.js
export function down(knex) {
return Promise.all([knex.schema.dropTable("customers")]);
}
export function up(knex) {
return Promise.all([
knex.schema.createTable("customers", function (table) {
// https://knexjs.org/#Schema-Building
table.uuid("id").notNullable().primary();
table.string("first_name", 50).notNullable();
table.string("last_name", 50).notNullable();
table.string("email", 100).index().notNullable();
// table.timestamp("created_at").defaultTo(knex.fn.now());
// table.timestamp("updated_at").defaultTo(knex.fn.now());
table.timestamps(false, true);
}),
]);
}
有什么线索吗?
来回几个小时后,它通过以这种方式更改 knexfile.js
来工作:
import dotenv from "dotenv";
import path from "path";
dotenv.config();
const config = {
// ...configurations as usual for any database/profile
};
export default config; // MUST be the default export!!!
[x80486@uplink:~/Workshop/Development/node-express]$ npx knex --esm migrate:latest
Using environment: sandbox
[
{
sql: "select * from sqlite_master where type = 'table' and name = ?",
output: [Function: output],
bindings: [ 'knex_schema_history' ]
}
]
...
[
{
sql: 'create table `customers` (`id` char(36) not null, `first_name` varchar(50) not null, `last_name` varchar(50) not null, `email` varchar(100) not null, `created_at` datetime not null default CURRENT_TIMESTAMP, `updated_at` datetime not null default CURRENT_TIMESTAMP, primary key (`id`))',
bindings: []
},
{
sql: 'create index `customers_email_index` on `customers` (`email`)',
bindings: []
}
]
{
method: 'insert',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ 1, 2021-03-03T01:04:00.988Z, '20210302134908_init.js' ],
__knexQueryUid: 'lO1x3i-L3FBDofzFXN8tB',
sql: 'insert into `knex_schema_history` (`batch`, `migration_time`, `name`) values (?, ?, ?)'
}
{
method: 'update',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ 0 ],
__knexQueryUid: '1PDbw3WTPPukvhtfjxWYt',
sql: 'update `knex_schema_history_lock` set `is_locked` = ?'
}
Batch 1 run: 1 migrations
以防万一您使用的是打字稿并且遇到类似的挑战。我在创建迁移文件时遇到了挑战:knex migrate:make create_users_table -x ts
。对 OP 的回答稍作调整对我有所帮助。
//knexfile.ts same directory as .env
import type { Knex } from "knex";
//I didn't import dotenv. it was already imported in src/config/index.
//and my knex instance has been set to use `development` as
//env
import envVariables from "./src/config/index";
const {dbClient, dbUser, dbPassword, dbDatabase, dbDatabaseTest} =
envVariables;
const config: { [key: string]: Knex.Config } = {
//Config as usual...
}
export default config;
//src/config/index
import 'dotenv/config';
export default {
port: process.env.APP_PORT,
appName: process.env.APP_NAME,
appEnv: process.env.APP_ENV || "development",
appKey: process.env.APP_KEY,
appUrl: process.env.APP_URL,
dbClient: process.env.DB_CLIENT,
dbUser: process.env.DB_USER,
dbPassword: process.env.DB_PASSWORD,
dbDatabase: process.env.DB_DATABASE,
dbDatabaseTest: process.env.DB_DATABASE_TEST,
};