如何修复KnexJs中undefined的error destroy

How to fix in KnexJs the error destroy of undefined

在我的 Node 应用程序中,我 运行 一个脚本来生成一个使用 KnexJs 查询生成器和 PostgreSQL

的数据库

我遇到的错误

Cannot read property 'destroy' of undefined
TypeError: Cannot read property 'destroy' of undefined
    at process.value (/app/node_modules/knex/lib/knex-builder/make-knex.js:91:26)
    at process.emit (events.js:315:20)
    at process.exit (internal/process/per_thread.js:169:15)
    at success (/app/node_modules/knex/bin/utils/cli-config-utils.js:76:11)
    at Command.<anonymous> (/app/node_modules/knex/bin/cli.js:236:9)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

我运行的脚本如下

const conn = {
  host: process.env.POSTGRES_HOST,
  database: process.env.POSTGRES_USER,
  user: process.env.POSTGRES_USER,
  password: process.env.POSTGRES_PASSWORD,
  port: process.env.POSTGRES_PORT,
  charset: 'utf8',
};

const databaseName = process.env.POSTGRES_DB;

const knex = require('knex')({ client: 'pg', connection: conn });

knex
  .raw('CREATE DATABASE ??', databaseName)
  .then(() => console.info('Successfully created db: ' + databaseName))
  .catch((err) =>
    console.warn('Warning: Unable to create db. Probably already exists.', err)
  )
  .finally(() => knex.destroy())
  .then(() => {
    const connection2 = knex({
      client: 'pg',
      connection: { ...conn, database: databaseName },
    });
    return connection2
      .raw('CREATE EXTENSION IF NOT EXISTS citext')
      .then(() => console.info('Successfully created extension citext'))
      .catch((err) => console.error('Unable to create extension citext.', err))
      .finally(() => connection2.destroy());
  })
  .then(() => process.exit(0));

我无法理解导致此问题的原因和原因

我认为这个问题可能是由于对什么是 knex 实例和什么是连接实例的误解造成的。

本部分:

const knex = require('knex')({ client: 'pg', connection: conn });

您使用 knex 模块定义了一个连接。因此,当您调用“knex”在下方创建第二个连接时:

 .then(() => {
    const connection2 = knex({
      client: 'pg',
      connection: { ...conn, database: databaseName },
    });

connection2 不是连接,因为 knex 在这种情况下 是所需的连接 。您可以使用以前的 knex 连接对象。

为避免这些问题,我建议您将事物分开并重命名变量以使其更易于解释:

const knex = require('knex') // this is the knex module

const connection = knex({ client: 'pg', connection: conn }) // This is a connection using knex

// So you should use `connection` instead `knex`, as you are using the connection instance to perform queries

connection
  .raw('CREATE DATABASE ??', databaseName)

// ...

.then(() => {
    // Now this should work and return a connection
    const connection2 = knex({
      client: 'pg',
      connection: { ...conn, database: databaseName },
    });

    // But as connection2 is actually the same of connection, it could be
    // const connection2 = connection;
    return connection2 // or return connection
      .raw('CREATE EXTENSION IF NOT EXISTS citext')
      .then(() => console.info('Successfully created extension citext'))
      .catch((err) => console.error('Unable to create extension citext.', err))
      .finally(() => connection2.destroy());
  })

要讨论的另一点是,如果真的有必要结束连接并在第一次 destroy() 调用后立即创建另一个连接。因为您可以拥有 connection 的实例,所以您可以在执行查询时使用它,如果不再需要它,只需将其销毁一次。