node / pg / PSQL:使用承诺创建表

时间:2019-07-01 12:26:45

标签: javascript node.js postgresql promise

我正在编写一个简单的Node / Express / React / Postgres应用程序,并且使用pg包与我的Postgres Server进行接口。

我需要三个表table1table2table3table2table1中有一个外键,而table3table 2中有一个外键,所以我在其中创建表的顺序是:table1然后table2然后table3

我试图在异步表创建调用中使用Promise强制执行此顺序。我通常遵循Brian Carlson's suggested Project Structure,但显然我做错了。

以下是我项目中相关的简化文件:

db.js:

const { Pool } = require('pg');

// Create pool connection to database
const pool = new Pool({
  user: XXXX,
  host: XXXX,
  database: XXXX,
  password: XXXX,
  port: XXXX
});

// Pool emitters
pool.on('connect', () => {
  console.log('Connected a client to the database');
});

pool.on('remove', () => {
  console.log('Disconnected a client from the database');
});

pool.on('error', (err, client) => {
  console.error('Unexpected error on idle client', err);
  process.exit(-1);
});

// This structure taken from Brian Carlson's pg API Documentation
// https://node-postgres.com/guides/project-structure
module.exports = {
  query: (text, params) => {
    console.log('Making a query!');
    return pool.query(text, params);
  }
};

table_scripts.js:

const db = require('../db');

const Database_Scripts = {
  create_table_1: () => {
    const create_table_1_query = {
      text: `CREATE TABLE IF NOT EXISTS
        public.table_1
      (
        id smallserial,
        name text NOT NULL,
        PRIMARY KEY (id)
      );`
    };
    return db.query(create_table_1_query);
  },

  create_table_2: () => {
    const create_table_2_query = {
      text: `CREATE TABLE IF NOT EXISTS
      public.table_2
    (
        id smallserial,
        table_1_id integer NOT NULL REFERENCES public.table_1(id),
        name text NOT NULL,
        PRIMARY KEY (id)
    );`
    };
    return db.query(create_table_2_query);
  },

  create_projects_table: () => {
    const create_table_3_query = {
      text: `
      CREATE TABLE IF NOT EXISTS
          public.table_3
          (
           id smallserial,
           table_3_id integer NOT NULL REFERENCES public.table_2(id),
           name text NOT NULL,
           PRIMARY KEY (id)
          );`
    };

    return db.query(create_table_3_query);
  }
};

module.exports = Database_Scripts;

create_tables.js:

const Table_Scripts = require('./table_scripts');

Table_Scripts.create_table_1()
  .then(Table_Scripts.create_table_2())
  .then(Table_Scripts.create_table_3())
  .catch(error => console.log(error.stack));

package.json:

{
  "name": "app",
  "version": "0.0.0",
  "scripts": {
    "start": "nodemon ./bin/www",
    "create_tables": "node ./database/scripts/create_tables.js"
  }
}

运行create_tables脚本(npm run-script create_tables)时,出现以下(已清除)错误:

Connected a client to the database
Connected a client to the database
Connected a client to the database
Disconnected a client from the database
(node:13444) UnhandledPromiseRejectionWarning: error: relation "public.table_1" does not exist
(node:13444) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a
catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:13444) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Disconnected a client from the database
(node:13444) UnhandledPromiseRejectionWarning: error: relation "public.table_2" does not exist
(node:13444) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a
catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
Disconnected a client from the database

我已经能够获取此脚本以将功能转换为异步功能,但是,我真的很想了解我在这里做错了什么。

1 个答案:

答案 0 :(得分:0)

您的问题似乎是尽管明确需要执行相反的操作,但是您正在同时创建表。

根据documentation,如果没有提供回调函数作为第三个参数,则pool.query()将返回promise。您需要等待每个db.query()承诺都得到解决。因此,它将等待创建第一个表,然后创建第二个表,最后创建第三个表。

我建议使用async / await语法

async function createTables () {
    try {
        const create_table_1_query = {
            text: `yourQuery1`
        };
        // awaits for the first table to be created
        await db.query(create_table_1_query);

        const create_table_2_query = {
            text: `yourQuery2`
        };
        // awaits for the second table to be created
        await db.query(create_table_2_query);

        const create_table_3_query = {
            text: `yourQuery3`
        };
        // awaits for the third table to be created
        await db.query(create_table_3_query);
    } catch (e) {
        console.error(e.stack);
    }
}

module.exports.createTables = createTables;

然后您可以致电await createTables();