【问题标题】:Postgres sql script to manage database in nodejsPostgres sql脚本在nodejs中管理数据库
【发布时间】:2019-11-29 16:42:16
【问题描述】:

我正在尝试从 node.js 自动创建数据库并删除 postgres sql 上的表。我编写了一个运行良好的脚本,但它的行为方式很奇怪。我先把代码贴在这里再解释一下这个问题。

db.js 文件

      require('dotenv').config()

  const { Pool } = require('pg')
  const isProduction = process.env.NODE_ENV === 'production'

  // don't try to load .env file on Heroku
  if (process.env.NODE_ENV !== 'production') {
    require('dotenv').config()
  }

  // get the current environment
  var env = process.env.NODE_ENV

  console.log(env);

  // convert to uppercase
  var envString = env.toUpperCase()

  // access the environment variables for this environment
  var DB_USER = process.env['DB_USER_' + envString]
  var DB_PASSWORD = process.env['DB_PASSWORD_' + envString]
  var DB_HOST = process.env['DB_HOST_' + envString]
  var DB_PORT = process.env['DB_PORT_' + envString]
  var DB_DATABASE = process.env['DB_DATABASE_' + envString]

  const connectionString = `postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE}`

  const pool = new Pool({
    connectionString: connectionString
  });

  pool.on('connect', () => {
    console.log('connected to the database');
  });

  /**
   * Create Users Table
   */
  const createUsersTable = () => {
    const queryText =
      `CREATE TABLE IF NOT EXISTS users (
          userId SERIAL PRIMARY KEY,
          firstName VARCHAR (50) NOT NULL,
          lastName VARCHAR (50) NOT NULL,
          email VARCHAR (50) NOT NULL,
          password VARCHAR (255) NOT NULL,
          gender VARCHAR(10) check (gender in ('Male', 'Female')),
          jobRole VARCHAR(10) check (jobRole in ('Admin', 'User')),
          department VARCHAR (100) NOT NULL,
          address VARCHAR (100) NOT NULL,
          createdOn TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
          UNIQUE (email)
        )`;

    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
   * Create GIFs Table
   */
  const createGifsTable = () => {
    const queryText =
      `CREATE TABLE IF NOT EXISTS Gifs (
          gifId SERIAL PRIMARY KEY,
          image VARCHAR (50) NOT NULL,
          title VARCHAR (50) NOT NULL,
          flags INTEGER DEFAULT 0,
          userId INTEGER REFERENCES Users(userId) ON DELETE CASCADE,
          createdOn TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
        )`;

    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
   * Create Articles Table
   */
  const createArticlesTable = () => {
    const queryText =
      `CREATE TABLE IF NOT EXISTS Articles (
          articleId SERIAL PRIMARY KEY,
          title VARCHAR (100) NOT NULL,
          article TEXT NOT NULL,
          flags INTEGER DEFAULT 0,
          userId INTEGER REFERENCES Users(userId) ON DELETE CASCADE,
          createdOn TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
        )`;

    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
   * Create Category Table
   */
  const createCategoryTable = () => {
    const queryText =
      `CREATE TABLE IF NOT EXISTS Category (
          categoryId SERIAL PRIMARY KEY,
          category VARCHAR (50) NOT NULL,
          articleId INTEGER REFERENCES Articles(articleId) ON DELETE CASCADE,
          createdOn TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
        )`;

    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Create ArticleComments Table
  */
  const createArticleCommentsTable = () => {
    const queryText =
      `CREATE TABLE IF NOT EXISTS ArticleComments (
          commentId SERIAL PRIMARY KEY,
          comment TEXT NOT NULL,
          flags INTEGER DEFAULT 0,
          articleId INTEGER REFERENCES Articles(articleId) ON DELETE CASCADE,
          createdOn TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
        )`;

    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Create GifComments Table
  */
  const createGifCommentsTable = () => {
    const queryText =
      `CREATE TABLE IF NOT EXISTS GifComments (
          commentId SERIAL PRIMARY KEY,
          comment TEXT NOT NULL,
          flags INTEGER DEFAULT 0,
          gifId INTEGER REFERENCES Gifs(gifId) ON DELETE CASCADE,
          createdOn TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
        )`;

    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Drop Users Table
  */
  const dropUsersTable = () => {
    const queryText = 'DROP TABLE IF EXISTS Users';
    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Drop Gifs Table
  */
  const dropGifsTable = () => {
    const queryText = 'DROP TABLE IF EXISTS Gifs';
    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Drop Articles Table
  */
  const dropArticlesTable = () => {
    const queryText = 'DROP TABLE IF EXISTS Articles';
    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Drop Category Table
  */
  const dropCategoryTable = () => {
    const queryText = 'DROP TABLE IF EXISTS Category';
    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Drop ArticleComments Table
  */
  const dropArticleCommentsTable = () => {
    const queryText = 'DROP TABLE IF EXISTS ArticleComments';
    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Drop GifComments Table
  */
  const dropGifCommentsTable = () => {
    const queryText = 'DROP TABLE IF EXISTS GifComments';
    pool.query(queryText)
      .then((res) => {
        console.log(res);
        pool.end();
      })
      .catch((err) => {
        console.log(err);
        pool.end();
      });
  }

  /**
  * Create All Tables
  */
  const createAllTables = () => {
    createUsersTable();
    createGifsTable();
    createArticlesTable();
    createCategoryTable();
    createArticleCommentsTable();
    createGifCommentsTable();
  }
  /**
  * Drop All Tables
  */
  const dropAllTables = () => {
    dropArticleCommentsTable();
    dropGifCommentsTable();
    dropCategoryTable();
    dropGifsTable();
    dropArticlesTable();
    dropUsersTable();
  }

  pool.on('remove', () => {
    console.log('client removed');
    process.exit(0);
  });


  module.exports = {
    createUsersTable,
    createGifsTable,
    createArticlesTable,
    createCategoryTable,
    createArticleCommentsTable,
    createGifCommentsTable,
    createAllTables,
    dropUsersTable,
    dropGifsTable,
    dropArticlesTable,
    dropCategoryTable,
    dropArticleCommentsTable,
    dropGifCommentsTable,
    dropAllTables
  };

  require('make-runnable');

在这个文件中,我创建了单独的函数来创建和删除数据库表。我在 package.js 上的脚本如下所示:

"scripts": {
  "start": "NODE_ENV=dev nodemon server.js",
  "test": "NODE_ENV=test mocha --exit",
  "dbCreate": "NODE_ENV=dev node -e 'require(\"./db\").createAllTables()'"
}

最后,由于我已将 db.js 中的所有单独创建表命令添加到 createAllTables 函数并将其添加到脚本中,因此我希望在从命令运行命令 npm run dbCreate 时创建表行。

我的问题

当我执行命令npm run dbCreate 时,它会创建总共 1 或 2 个表。当我再次执行时,它会另外创建一个或两个表。因此,对于要创建的所有表,我必须重复执行命令,但我希望一次性完成。当我用dropAllTables 替换createAllTables 函数时,也会发生同样的事情。有什么我做错了吗?我想在运行自动化测试时使用这个脚本。

【问题讨论】:

    标签: node.js postgresql express node-pg-pool


    【解决方案1】:

    尽量不要在回调中调用pool.end()。我目前没有时间进行测试,但看起来正在发生的事情是您正在关闭连接然后没有重新打开它,因此由于它们是异步的,您可能能够在第一个解决之前关闭两个命令,但一旦第一个查询完成,它总是会停止。

    【讨论】:

      猜你喜欢
      • 2020-11-24
      • 2012-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多