Ubuntu20.04でNode.jsでPostgreSQLを使用する方法

提供:Dev Guides
移動先:案内検索

著者は、 Society of Women Engineers を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

Node.js エコシステムは、データベースとのインターフェースのための一連のツールを提供します。 それらのツールの1つは、 node-postgres です。これには、Node.jsがPostgreSQLデータベースとインターフェイスできるようにするモジュールが含まれています。 node-postgresを使用すると、PostgreSQLデータベースのデータにアクセスして保存できるNode.jsプログラムを作成できます。

このチュートリアルでは、node-postgresを使用して、PostgreSQL(略してPostgres)データベースに接続してクエリを実行します。 まず、Postgresでデータベースユーザーとデータベースを作成します。 次に、node-postgresモジュールを使用してアプリケーションをPostgresデータベースに接続します。 その後、node-postgresを使用して、PostgreSQLデータベースのデータを挿入、取得、および変更します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • sudo権限を持ち、Ubuntu20.04でファイアウォールが有効になっているroot以外のユーザーアカウント。 チュートリアルUbuntu20.04 を使用したサーバーの初期セットアップに従って、サーバーをセットアップします。
  • UbuntuにインストールされたNode.js。 Node.jsをインストールしていない場合は、 Ubuntu20.04にNode.jsをインストールする方法に従ってください。
  • サーバーにPostgreSQLがインストールされています。 ガイドUbuntu20.04にPostgreSQLをインストールして使用する方法に従って、UbuntuにPostgreSQLをインストールします。
  • PostgreSQLでクエリを作成する方法の基本的な知識。詳細については、PostgreSQLでのクエリの概要を参照してください。
  • Node.jsプログラムの作成方法の基本については、Node.jsで最初のプログラムを作成して実行する方法を参照してください。
  • JavaScriptで非同期関数を作成する方法の基本的な理解。 基本を学ぶために、 JavaScript チュートリアルでのイベントループ、コールバック、プロミス、および非同期/待機について理解してください。

ステップ1-プロジェクトディレクトリの設定

このステップでは、ノードアプリケーションのディレクトリを作成し、npmを使用してnode-postgresをインストールします。 このディレクトリは、相互作用するPostgreSQLデータベースと構成ファイルの構築に取り組む場所です。

mkdirコマンドを使用して、プロジェクトのディレクトリを作成します。

mkdir node_pg_app

cdコマンドを使用して、新しく作成されたディレクトリに移動します。

cd node_pg_app

npm initコマンドを使用して、package.jsonファイルでディレクトリを初期化します。

 npm init -y

-yフラグは、デフォルトのpackage.jsonファイルを作成します。

次に、node-postgresモジュールをnpm installとともにインストールします。

npm install pg

これで、プロジェクトのディレクトリが設定され、依存関係としてnode-postgresがインストールされました。 これで、Postgresでユーザーとデータベースを作成する準備が整いました。

ステップ2—PostgreSQLでデータベースユーザーとデータベースを作成する

このステップでは、アプリケーションのデータベースユーザーとデータベースを作成します。

初めてUbuntuにPostgresをインストールすると、システムにユーザーpostgrespostgresという名前のデータベースユーザー、およびデータベースpostgresが作成されます。 ユーザーpostgresを使用すると、ユーザーやデータベースの作成などの管理タスクを実行できるPostgreSQLセッションを開くことができます。

PostgreSQLはidentauthentication 接続スキームを使用します。これにより、Ubuntuのユーザーは、ユーザー名がPostgresユーザーと類似している限り、Postgresシェルにログインできます。 Ubuntuにはすでにpostgresユーザーがいて、PostgreSQLにはpostgresユーザーが作成されているので、Postgresシェルにログインできます。

ログインするには、Ubuntuユーザーをsudopostgresに切り替え、psqlコマンドを使用してPostgresシェルにログインします。

sudo -u postgres psql

コマンドの引数は次のことを表します。

  • -u:Ubuntuでユーザーを特定のユーザーに切り替えるフラグ。 postgres userを引数として渡すと、Ubuntuのユーザーがpostgresに切り替わります。
  • psql:SQLコマンドを入力してデータベース、ロール、テーブルなどを作成できるPostgresインタラクティブターミナルプログラム。

Postgresシェルにログインすると、ターミナルは次のようになります。


postgresは、操作するデータベースの名前であり、#は、スーパーユーザーとしてログインしていることを示します。

Nodeアプリケーションの場合、アプリケーションがPostgresへの接続に使用する個別のユーザーとデータベースを作成します。

これを行うには、強力なパスワードを使用して新しい役割を作成します。

CREATE USER fish_user WITH PASSWORD 'password';

Postgresでの役割は、ユースケースに応じてユーザーまたはグループと見なすことができます。 このチュートリアルでは、ユーザーとして使用します。

次に、データベースを作成し、作成したユーザーに所有権を割り当てます。

CREATE DATABASE fish OWNER fish_user;

データベースの所有権をfish_userに割り当てると、fishデータベースのテーブルにデータを作成、削除、および挿入するための役割権限が付与されます。

ユーザーとデータベースを作成したら、Postgresインタラクティブシェルを終了します。

\q

fish_userとしてPostgresシェルにログインするには、作成したPostgresユーザーと同様の名前でUbuntuにユーザーを作成する必要があります。

adduserコマンドを使用してユーザーを作成します。

sudo adduser fish_user

これで、Ubuntuでユーザー、PostgreSQLユーザー、およびNodeアプリケーション用のデータベースが作成されました。 次に、fish_userを使用してPostgreSQLインタラクティブシェルにログインし、テーブルを作成します。

ステップ3—ロールを使用してPostgresシェルを開き、テーブルを作成する

このセクションでは、Ubuntuで前のセクションで作成したユーザーでPostgresシェルを開きます。 シェルにログインしたら、Node.jsアプリのテーブルを作成します。

fish_userとしてシェルを開くには、次のコマンドを入力します。

 sudo -u fish_user psql -d fish

sudo -u fish_userは、Ubuntuユーザーをfish_userに切り替えてから、そのユーザーとしてpsqlコマンドを実行します。 -dフラグは、接続するデータベース(この場合はfish)を指定します。 データベースを指定しない場合、psqlはデフォルトでfish_userデータベースに接続しようとしますが、データベースは検出されず、エラーがスローされます。

psqlシェルにログインすると、シェルプロンプトは次のようになります。


fishは、fishデータベースに接続していることを示します。

\conninfoコマンドを使用して、接続を確認できます。

\conninfo

次のような出力が表示されます。

OutputYou are connected to database "fish" as user "fish_user" via socket in "/var/run/postgresql" at port "5432".

出力は、実際にfish_userとしてログインし、fishデータベースに接続していることを確認します。

次に、アプリケーションが挿入するデータを含むテーブルを作成します。

作成するテーブルは、サメの名前とその色を追跡します。 データを入力すると、次のようになります。

id 名前
1 サミー
2 ホセ ティール

SQL create tableコマンドを使用して、テーブルを作成します。

CREATE TABLE shark(
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
color VARCHAR(50) NOT NULL);

CREATE TABLE sharkコマンドは、次の3列のテーブルを作成します。

  • id:テーブルの自動インクリメントフィールドと主キー。 行を挿入するたびに、Postgresはid値をインクリメントして入力します。
  • nameおよびcolor:50文字を格納できるフィールド。 NOT NULLは、フィールドが空になるのを防ぐ制約です。

テーブルが適切な所有者で作成されているかどうかを確認します。

\dt

\dtコマンドは、データベース内のすべてのテーブルを一覧表示します。

コマンドを実行すると、出力は次のようになります。

         List of relations
 Schema | Name  | Type  |   Owner
--------+-------+-------+-----------
 public | shark | table | fish_user
(1 row)

出力は、fish_usersharkテーブルを所有していることを確認します。

次に、Postgresシェルを終了します。

\q

プロジェクトディレクトリに戻ります。

テーブルを作成したら、node-postgresモジュールを使用してPostgresに接続します。

ステップ4—Postgresデータベースに接続する

このステップでは、node-postgresを使用して、Node.jsアプリケーションをPostgreSQLデータベースに接続します。 これを行うには、node-postgresを使用して接続プールを作成します。 接続プールはデータベース接続のキャッシュとして機能し、アプリがすべてのデータベース要求に接続を再利用できるようにします。 これにより、アプリケーションを高速化し、サーバーリソースを節約できます。

お好みのエディタでdb.jsファイルを作成して開きます。 このチュートリアルでは、ターミナルテキストエディタであるnanoを使用します。

nano db.js

db.jsファイルで、node-postgresモジュールを要求し、破壊割り当てを使用して、node-postgresからクラスPoolを抽出します。

node_pg_app / db.js

const { Pool } = require('pg')

次に、Poolインスタンスを作成して、接続プールを作成します。

node_pg_app / db.js

const { Pool} = require('pg')

const pool = new Pool({
  user: 'fish_user',
  database: 'fish',
  password: 'password',
  port: 5432,
  host: 'localhost',
})

Poolインスタンスを作成するときは、構成オブジェクトを引数として渡します。 このオブジェクトには、node-postgresがPostgresへの接続を確立するために使用する詳細が含まれています。

オブジェクトは、次のプロパティを定義します。

  • user:Postgresで作成したユーザー。
  • database:Postgresで作成したデータベースの名前。
  • password:ユーザーfish_userのパスワード。
  • port:Postgresがリッスンしているポート。 5432がデフォルトのポートです。
  • hostnode-postgresに接続するPostgresサーバー。 localhostを渡すと、node-postgresがシステムにインストールされているPostgresサーバーに接続されます。 Postgresサーバーが別のドロップレット上にある場合、hostは次のようになります:host: server_ip_address

注:本番環境では、構成値を.envファイルなどの別のファイルに保持することをお勧めします。 このファイルは、バージョン管理による追跡を回避するためにGitを使用している場合、.gitignoreファイルに追加されます。 利点は、passworduserdatabaseなどの機密情報を攻撃者から隠すことです。


インスタンスを作成すると、データベース接続が確立され、Poolオブジェクトがpool変数に格納されます。 これをアプリのどこでも使用するには、エクスポートする必要があります。 db.jsファイルで、Poolオブジェクトのインスタンスを要求して定義し、そのプロパティと値を設定します。

node_pg_app / db.js

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

const pool = new Pool({
  user: "fish_user",
  database: "fish",
  password: "password",
  port: 5432,
  host: "localhost",
});

module.exports = { pool };

ファイルを保存し、CTRL+Xを押してnanoを終了します。 yと入力して変更を保存し、Macの場合はENTERまたはRETURNキーを押してファイル名を確認します。

アプリケーションをPostgresに接続したので、この接続を使用してPostgresにデータを挿入します。

ステップ5—Postgresデータベースへのデータの挿入

このステップでは、db.jsファイルで作成した接続プールを使用して、PostgreSQLデータベースにデータを追加するプログラムを作成します。 プログラムが実行されるたびに異なるデータを挿入するようにするには、コマンドライン引数を受け入れる機能をプログラムに与えます。 プログラムを実行するときに、サメの名前と色を渡します。

エディターでinsertData.jsファイルを作成して開きます。

nano insertData.js

insertData.jsファイルに次のコードを追加して、スクリプトにコマンドライン引数を処理させます。

node_pg_app / insertData.js

const { pool } = require("./db");

async function insertData() {
  const [name, color] = process.argv.slice(2);
  console.log(name, color);
}

insertData();

まず、db.jsファイルからpoolオブジェクトを要求します。 これにより、プログラムはデータベース接続を使用してデータベースにクエリを実行できます。

次に、insertData()関数を、asyncキーワードを使用して非同期関数として宣言します。 これにより、awaitキーワードを使用して、データベース要求を非同期にすることができます。

insertData()関数内で、processモジュールを使用して、コマンドライン引数にアクセスします。 Node.js process.argvメソッドは、nodeおよびinsertData.js引数を含む配列内のすべての引数を返します。

たとえば、node insertData.js sammy blueを使用してターミナルでスクリプトを実行すると、process.argvメソッドは配列['node', 'insertData.js', 'sammy', 'blue']を返します(配列は簡潔にするために編集されています)。

最初の2つの要素nodeinsertData.jsをスキップするには、JavaScriptのslice()メソッドをprocess.argvメソッドに追加します。 これにより、インデックス2以降の要素が返されます。 次に、これらの引数はname変数とcolor変数に分解されます。

ファイルを保存し、CTRL+Xnanoを終了します。 nodeを使用してファイルを実行し、引数sammyおよびblueを渡します。

node insertData.js sammy blue

コマンドを実行すると、次の出力が表示されます。

Outputsammy blue

この関数は、コマンドライン引数からnameおよびsharkcolorにアクセスできるようになりました。 次に、insertData()関数を変更して、sharkテーブルにデータを挿入します。

テキストエディタでinsertData.jsファイルを再度開き、強調表示されたコードを追加します。

node_pg_app / insertData.js

const { pool } = require("./db");

async function insertData() {
  const [name, color] = process.argv.slice(2);
  const res = await pool.query(
      "INSERT INTO shark (name, color) VALUES ($1, $2)",
      [name, color]
    );
  console.log(`Added a shark with the name ${name}`);
}

insertData();

ここで、insertData()関数は、サメのnamecolorを定義します。 次に、SQLステートメントINSERT INTO shark (name, color) ...を最初の引数として取るnode-postgresからのpool.queryメソッドを待機します。 SQLステートメントは、sharkテーブルにレコードを挿入します。 これは、パラメーター化されたクエリと呼ばれるものを使用します。 $1、および$2は、pool.query()メソッドで2番目の引数として提供される配列のnameおよびcolor変数に対応します。[ X152X]。 Postgresがステートメントを実行しているとき、変数はSQLインジェクションからアプリケーションを安全に保護するために置き換えられます。 クエリの実行後、関数はconsole.log()を使用して成功メッセージをログに記録します。

スクリプトを実行する前に、insertData()関数内のコードをtry ... catch ブロックにラップして、ランタイムエラーを処理します。

node_pg_app / insertData.js

const { pool } = require("./db");

async function insertData() {
  const [name, color] = process.argv.slice(2);
  try {
    const res = await pool.query(
      "INSERT INTO shark (name, color) VALUES ($1, $2)",
      [name, color]
    );
    console.log(`Added a shark with the name ${name}`);
  } catch (error) {
    console.error(error)
  }
}

insertData()

関数が実行されると、tryブロック内のコードが実行されます。 成功すると、関数はcatchブロックをスキップして終了します。 ただし、tryブロック内でエラーがトリガーされた場合、catchブロックが実行され、コンソールにエラーが記録されます。

これで、プログラムはコマンドライン引数を取り、それらを使用してsharkテーブルにレコードを挿入できます。

保存して、テキストエディタを終了します。 コマンドライン引数としてsammyおよびblueを指定してinsertData.jsファイルを実行します。

node insertData.js sammy blue

次の出力が表示されます。

OutputAdded a shark with the name sammy

コマンドを実行すると、名前がsammy、色がblueのサメテーブルにレコードが挿入されます。

次に、コマンドライン引数としてjoseおよびtealを使用してファイルを再実行します。

node insertData.js jose teal

出力は次のようになります。

OutputAdded a shark with the name jose

これは、sharkテーブルにjoseという名前とtealの色で別のレコードを挿入したことを確認します。

これで、sharkテーブルに2つのレコードが挿入されました。 次のステップでは、データベースからデータを取得します。

ステップ6—Postgresデータベースからデータを取得する

このステップでは、node-postgresを使用してsharkテーブル内のすべてのレコードを取得し、それらをコンソールにログインします。

お気に入りのエディタでファイルretrieveData.jsを作成して開きます。

nano retrieveData.js

retrieveData.jsに、データベースからデータを取得するための次のコードを追加します。

node_pg_app / retrieveData.js

const { pool } = require("./db");

async function retrieveData() {
  try {
    const res = await pool.query("SELECT * FROM shark");
    console.log(res.rows);
  } catch (error) {
    console.error(error);
  }
}

retrieveData()

retrieveData()関数は、sharkテーブルのすべての行を読み取り、コンソールに記録します。 関数tryブロック内で、SQLステートメントを引数としてnode-postgresからpool.query()メソッドを呼び出します。 SQLステートメントSELECT * FROM sharkは、sharkテーブル内のすべてのレコードを取得します。 それらが取得されると、console.log()ステートメントは行をログに記録します。

エラーがトリガーされた場合、実行はcatchブロックにスキップし、エラーをログに記録します。 最後の行で、retrieveData()関数を呼び出します。

次に、エディターを保存して閉じます。 retrieveData.jsファイルを実行します。

node retrieveData.js

次のような出力が表示されます。

Output[
  { id: 1, name: 'sammy', color: 'blue' },
  { id: 2, name: 'jose', color: 'teal' }
]

node-postgresは、JSONのようなオブジェクトでテーブルの行を返します。 これらのオブジェクトは配列に格納されます。

これで、データベースからデータを取得できます。 次に、node-postgresを使用してテーブル内のデータを変更します。

ステップ7—Postgresデータベースのデータを変更する

このステップでは、node-postgresを使用してPostgresデータベースのデータを変更します。 これにより、sharkテーブルレコードのデータを変更できます。

idnameの2つのコマンドライン引数を取るスクリプトを作成します。 id値を使用して、テーブルに必要なレコードを選択します。 name引数は、名前を変更するレコードの新しい値になります。

modifyData.jsファイルを作成して開きます。

nano modifyData.js

modifyData.jsファイルに、次のコードを追加して、sharkテーブルのレコードを変更します。

node_pg_app / modifyData.js

const { pool } = require("./db");

async function modifyData() {
  const [id, name] = process.argv.slice(2);
  try {
    const res = await pool.query("UPDATE shark SET name = $1 WHERE id = $2", [
      name,
      id,
    ]);
    console.log(`Updated the shark name to ${name}`);
  } catch (error) {
    console.error(error);
  }
}

modifyData();

まず、modifyData.jsファイルのdb.jsファイルからpoolオブジェクトが必要です。

次に、非同期関数modifyData()を定義して、Postgresのレコードを変更します。 関数内で、破棄割り当てを使用して、コマンドライン引数から2つの変数idnameを定義します。

tryブロック内で、最初の引数としてSQLステートメントを渡すことにより、node-postgresからpool.queryメソッドを呼び出します。 UPDATE SQLステートメントで、WHERE句は、id値に一致するレコードを選択します。 選択すると、SET name = $1 は名前フィールドの値を新しい値に変更します。

次に、console.logは、レコード名が変更されると実行されるメッセージをログに記録します。 最後に、最後の行でmodifyData()関数を呼び出します。

CTRL+Xを使用して、ファイルを保存して終了します。 2sanを引数としてmodifyData.jsファイルを実行します。

node modifyData.js 2 san

次の出力が表示されます。

OutputUpdated the shark name to san

レコード名がjoseからsanに変更されたことを確認するには、retrieveData.jsファイルを実行します。

node retrieveData.js

次のような出力が得られます。

Outputoutput
[
  { id: 1, name: 'sammy', color: 'blue' },
  { id: 2, name: 'san', color: 'teal' }
]

これで、IDが2のレコードの名前が、joseの代わりにsanになっていることがわかります。

これで、node-postgresを使用してデータベース内のレコードが正常に更新されました。

結論

このチュートリアルでは、node-postgresを使用して、Postgresデータベースに接続してクエリを実行しました。 まず、Postgresでユーザーとデータベースを作成しました。 次に、テーブルを作成し、node-postgresを使用してアプリケーションをPostgresに接続し、node-postgresモジュールを使用してPostgresでデータを挿入、取得、および変更しました。

node-postgresの詳細については、ドキュメントにアクセスしてください。 Node.jsのスキルを向上させるために、Node.jsシリーズのコーディング方法を調べることができます。