著者は、 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をインストールすると、システムにユーザーpostgres、postgresという名前のデータベースユーザー、およびデータベースpostgresが作成されます。 ユーザーpostgresを使用すると、ユーザーやデータベースの作成などの管理タスクを実行できるPostgreSQLセッションを開くことができます。
PostgreSQLはidentauthentication 接続スキームを使用します。これにより、Ubuntuのユーザーは、ユーザー名がPostgresユーザーと類似している限り、Postgresシェルにログインできます。 Ubuntuにはすでにpostgresユーザーがいて、PostgreSQLにはpostgresユーザーが作成されているので、Postgresシェルにログインできます。
ログインするには、Ubuntuユーザーをsudoでpostgresに切り替え、psqlコマンドを使用してPostgresシェルにログインします。
- sudo -u postgres psql
コマンドの引数は次のことを表します。
-u:Ubuntuでユーザーを特定のユーザーに切り替えるフラグ。postgresuserを引数として渡すと、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_userがsharkテーブルを所有していることを確認します。
次に、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を抽出します。
const { Pool } = require('pg')
次に、Poolインスタンスを作成して、接続プールを作成します。
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がデフォルトのポートです。host:node-postgresに接続するPostgresサーバー。localhostを渡すと、node-postgresがシステムにインストールされているPostgresサーバーに接続されます。 Postgresサーバーが別のドロップレット上にある場合、hostは次のようになります:host: server_ip_address。
注:本番環境では、構成値を.envファイルなどの別のファイルに保持することをお勧めします。 このファイルは、バージョン管理による追跡を回避するためにGitを使用している場合、.gitignoreファイルに追加されます。 利点は、password、user、databaseなどの機密情報を攻撃者から隠すことです。
インスタンスを作成すると、データベース接続が確立され、Poolオブジェクトがpool変数に格納されます。 これをアプリのどこでも使用するには、エクスポートする必要があります。 db.jsファイルで、Poolオブジェクトのインスタンスを要求して定義し、そのプロパティと値を設定します。
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ファイルに次のコードを追加して、スクリプトにコマンドライン引数を処理させます。
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つの要素nodeとinsertData.jsをスキップするには、JavaScriptのslice()メソッドをprocess.argvメソッドに追加します。 これにより、インデックス2以降の要素が返されます。 次に、これらの引数はname変数とcolor変数に分解されます。
ファイルを保存し、CTRL+Xでnanoを終了します。 nodeを使用してファイルを実行し、引数sammyおよびblueを渡します。
- node insertData.js sammy blue
コマンドを実行すると、次の出力が表示されます。
Outputsammy blue
この関数は、コマンドライン引数からnameおよびsharkcolorにアクセスできるようになりました。 次に、insertData()関数を変更して、sharkテーブルにデータを挿入します。
テキストエディタで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()関数は、サメのnameとcolorを定義します。 次に、SQLステートメントINSERT INTO shark (name, color) ...を最初の引数として取るnode-postgresのpool.queryメソッドを待機します。 SQLステートメントは、sharkテーブルにレコードを挿入します。 これは、パラメーター化されたクエリと呼ばれるものを使用します。 $1、および$2は、pool.query()メソッドで2番目の引数として提供される配列のnameおよびcolor変数に対応します。[ X152X]