Ubuntu20.04でNode.jsでPostgreSQLを使用する方法
著者は、 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でユーザーを特定のユーザーに切り替えるフラグ。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_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
を抽出します。
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
がデフォルトのポートです。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
オブジェクトのインスタンスを要求して定義し、そのプロパティと値を設定します。
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つの要素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
ファイルを再度開き、強調表示されたコードを追加します。
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()
関数は、サメのname
とcolor
を定義します。 次に、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
テーブルレコードのデータを変更できます。
id
とname
の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つの変数id
とname
を定義します。
try
ブロック内で、最初の引数としてSQLステートメントを渡すことにより、node-postgres
からpool.query
メソッドを呼び出します。 UPDATE
SQLステートメントで、WHERE
句は、id
値に一致するレコードを選択します。 選択すると、SET name = $1
は名前フィールドの値を新しい値に変更します。
次に、console.log
は、レコード名が変更されると実行されるメッセージをログに記録します。 最後に、最後の行でmodifyData()
関数を呼び出します。
CTRL+X
を使用して、ファイルを保存して終了します。 2
とsan
を引数として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シリーズのコーディング方法を調べることができます。