web-dev-qa-db-ja.com

アプリの起動時にpg-promiseでデータベース接続を確認します

pg-promise モジュールを使用してpostgresデータベースに接続するエクスプレスアプリケーションを構築しています。

アプリケーションサーバーの起動時にデータベース接続が成功することを確認したいと思います。つまり、データベースへの接続が失敗した場合、エラーをスローしたいと思います。

私のserver.jsファイルは次のとおりです。

_const express = require("express");

const databaseConfig= {
  "Host": "localhost",
  "port": 5432,
  "database": "library_app",
  "user": "postgres"
};

const pgp = require("pg-promise")({});
const db = pgp(databaseConfig);

const app = express();
const port = 5000;

app.listen(port, (err) => {
  console.log(`running server on port: ${port}`);
});
_

現在の構成では、データベース接続が有効であるかどうかに関係なく、エクスプレスサーバーが開始されます

ドキュメントを閲覧しようとしましたが、解決策が見つかりませんでした。 const db = pgp(databaseConfig).catch((err) => { // blow up });も試してみましたが、pgpはプロミスを返さないため、うまくいきませんでした。

25
Steven L.

私は pg-promise ;)の著者です。そして、この質問が初めて尋ねられるのではないので、ここで詳細に説明します。

このような新しいデータベースオブジェクトをインスタンス化する場合:

const db = pgp(connection);

...それはすべて-オブジェクトを作成しますが、接続を試みません。ライブラリは接続プールの上に構築され、実際のクエリメソッドのみがプールからの接続を要求します。

公式ドキュメントから

オブジェクトdbは、遅延データベース接続を使用したデータベースプロトコルを表します。つまり、実際のクエリメソッドのみが接続を取得および解放します。したがって、接続の詳細ごとに1つのグローバル/共有dbオブジェクトのみを作成する必要があります。

ただし、以下に示すように、メソッド connect を使用して、クエリを実行せずに接続するようにライブラリに要求できます。

また、このメソッドはクエリをチェーンするための推奨される方法ではありませんが、 Tasks のサポートが導入されて以来(より安全なアプローチとして)、一般的な接続のチェックに役立ちます。

私は自分の投稿から例をコピーしました: https://github.com/vitaly-t/pg-promise/issues/81

以下は、2つの方法で同時に実行する例です。そのため、どちらのアプローチを選択することもできます。

const initOptions = {
    // global event notification;
    error(error, e) {
        if (e.cn) {
            // A connection-related error;
            //
            // Connections are reported back with the password hashed,
            // for safe errors logging, without exposing passwords.
            console.log('CN:', e.cn);
            console.log('EVENT:', error.message || error);
        }
    }
};

const pgp = require('pg-promise')(initOptions);

// using an invalid connection string:
const db = pgp('postgresql://userName:password@Host:port/database');

db.connect()
    .then(obj => {
        obj.done(); // success, release the connection;
    })
    .catch(error => {
        console.log('ERROR:', error.message || error);
    });

出力:

CN: postgresql://userName:########@Host:port/database EVENT: getaddrinfo ENOTFOUND Host host:5432 ERROR: getaddrinfo ENOTFOUND Host host:5432

ライブラリ内のすべてのエラーは、最初にグローバル error イベントハンドラーを通じて報告され、その後、対応する.catchハンドラー内でエラーが報告されます。

代替案

接続を手動で確立する代わりに、次のような有効な接続に対して常に成功するタイプのクエリを実行できます。

db.proc('version')
    .then(data => {
        // SUCCESS
        // data.version =
        // 'PostgreSQL 9.5.1, compiled by Visual C++ build 1800, 64-bit'
    })
    .catch(error => {
        // connection-related error
    });

APIリンク:

47
vitaly-t