Каждый второй раз, когда я запускаю файл конфигурации, он не работает

#node.js #postgresql #node-postgres

Вопрос:

Я использую node.js w/ PSQL, наряду с express и node-postgres. У меня есть файл под названием config.js. Цель состоит в том, чтобы он удалял базу данных, а затем воссоздавал ее вместе с таблицами при каждом запуске. Это работает каждый второй раз, возвращая ошибку в другой половине времени и не создавая базу данных заново.

 (node:11300) UnhandledPromiseRejectionWarning: error: database "abc" does not exist
 

Кто-нибудь знает, в чем дело? Пожалуйста, скажите мне, нужно ли мне включать полное сообщение об ошибке, я этого не сделал, так как оно показалось мне не очень полезным.

Код:

 const { Pool, Client } = require('pg')

let dbName = "abc"

let tables = [{
    name: "users",
    content: "id SERIAL, username VARCHAR, email VARCHAR, passcode VARCHAR"
}]

let pool = new Pool({
    user: 'postgres',
    host: 'localhost',
    database: 'postgres',
    password: 'postgres',
    port: 5432
})

deleteDb()
createDbAndTables()

function deleteDb() {
    pool.query("DROP DATABASE IF EXISTS abc", (err, res) => {

        if (err) {

            console.log(err)
        } else {

            console.log("deleted db "   dbName)
        }
    })
}

function createDbAndTables() {
    pool.query("CREATE DATABASE abc", (err, res) => {

        console.log("created db "   dbName)

        const client = new Client({
            host: 'localhost',
            port: 5432,
            user: 'postgres',
            password: 'postgres',
            database: dbName,
        })

        client.connect()

        for (let i = 0; i < tables.length; i  ) {

            let table = tables[i]

            client.query("CREATE TABLE "   table.name   "("   table.content   ")", (err, res) => {
                if (err) {

                    console.log(err)
                } else {

                    console.log("created table "   table.name)
                }
                if (i == tables.length) {

                    client.end()
                }
            })
        }
        pool.end()
    })
}
 

Если есть вещи, которые я делаю неправильно, или оптимизации, которые могут быть сделаны, я также хотел бы их услышать.
Заранее спасибо за помощь!

Комментарии:

1. Похоже DROP DATABASE IF EXISTS abc на ошибки, когда бд не существует?

2. Я не уверен, что это все, так как база данных есть, я запускаю файл, и он возвращает ошибку.

3. О, теперь я это понимаю. Обе функции deleteDb и createDbAndTables запускают асинхронный код, но вы запускаете их не последовательно. У тебя здесь гоночное состояние. Вам придется подождать их, чтобы убедиться, что они работают в порядке

Ответ №1:

Вот очень быстрый и грязный способ убедиться, что обе ваши функции deleteDb createDbAndTables выполняются последовательно:

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

let dbName = 'abc';

let tables = [
  {
    name: 'users',
    content: 'id SERIAL, username VARCHAR, email VARCHAR, passcode VARCHAR',
  },
];

let pool = new Pool({
  user: 'postgres',
  host: 'localhost',
  database: 'postgres',
  password: 'postgres',
  port: 5432,
});

deleteDb().then(() => {
  createDbAndTables();
});

function deleteDb() {
  return new Promise((resolve, reject) => {
    pool.query('DROP DATABASE IF EXISTS abc', (err, res) => {
      if (err) {
        reject(err);
      } else {
        resolve('deleted db '   dbName);
      }
    });
  });
}

function createDbAndTables() {
  pool.query('CREATE DATABASE abc', (err, res) => {
    console.log('created db '   dbName);

    const client = new Client({
      host: 'localhost',
      port: 5432,
      user: 'postgres',
      password: 'postgres',
      database: dbName,
    });

    client.connect();

    for (let i = 0; i < tables.length; i  ) {
      let table = tables[i];
      client.query(
        'CREATE TABLE '   table.name   '('   table.content   ')',
        (err, res) => {
          if (err) {
            console.log(err);
          } else {
            console.log('created table '   table.name);
          }
          if (i == tables.length) {
            client.end();
          }
        }
      );
    }
    pool.end();
  });
}
 

Обратите внимание, что я дал обещание только одному из них, но вам, скорее всего, придется сделать это с обоими, если вы хотите запустить все позже.
Я также не использовал async / await , поскольку я предполагаю, что это не выполняется внутри функции, и у вас нет последнего запущенного узла для простоты.

Комментарии:

1. Спасибо! Теперь работает каждый раз. Отличный ответ.