クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【SQL】ターミナルからHerokuのPostgreSQLに接続する

DB操作の続きです。以前はMAMPのMySQLに接続しました。他にもJSON-ServerやMongoDBなどに接続してみましたが、これらは全てローカル環境のデータベースでした。今回はクラウド環境であるHerokuのPostgreSQLに接続してみます。MySQLと同じRDBでSQL文で操作できるDBです。それではいきましょう!

【目次】

※参考:前回記事
【SQL】ターミナルからMAMPのMySQLにCRUDする - クモのようにコツコツと

※参考:Web開発環境についてのまとめ
qiita.com

前回のおさらい

MAMPのMySQLに接続。CRUD処理も。

※参考:【SQL】ターミナルからMAMPのMySQLにCRUDする - クモのようにコツコツと

APIモックのJSON-Serverに接続。CRUD処理も。

※参考:【擬似NoSQL】ターミナルからAPIモックのJSON ServerにCRUDする - クモのようにコツコツと

NoSQLのMongoDBに接続。CRUD処理も。

※参考:【NoSQL】ターミナルからMongoDBにCRUDする(JS & JSONライク!) - クモのようにコツコツと

これらはすべてローカル環境のDBに接続した。今回はクラウド環境のHerokuのPostgreSQLに接続したい。

PostgreSQLとは

PostgreSQLはMySQLと同じRDB(リレーショナルデータベース)で、データの操作もSQL文を使う。

MySQLとPostgreSQLの比較

※参考:PostgreSQLとMySQL、使うならどっち? データベース専門家が8つの視点で徹底比較! - エンジニアHub|若手Webエンジニアのキャリアを考える!

PostgreSQLの公式サイト

※参考:PostgreSQL: The world's most advanced open source database

CRUD操作を調べる。SQL文の部分はMySQLと共通していそう。

※参考:PostgreSQLの基本的なコマンド - Qiita

※参考:【PostgreSQL】 基本的なCRUD操作 - Qiita

※参考:PostgreSQLのCRUD - Qiita

HerokuのPostgreSQLはアプリとの連携が必要

HerokuのPostgreSQLのチュートリアル。これを参考に進める。

※参考:Heroku Postgres | Heroku Dev Center

どうやらHerokuのPostgreSQLはHerokuアプリとの連携が必要なようだ。

(MAMPのMySQLはアプリと連携せずに単体でDBを作れた)

※参考:【SQL】ターミナルからMAMPのMySQLにCRUDする - クモのようにコツコツと


これまで自分が作ったHerokuアプリはPHP系とNode.js系。

PHP

※参考:ローカル→Sourcetree→GitHub→Herokuに同期する方法(黒い画面不要!) - クモのようにコツコツと

Laravel(PHPのフレームワーク)

※参考:LaravelをMAMP環境からHerokuにデプロイするためにやったこと調べたこと - クモのようにコツコツと

Express(Node.jsのフレームワーク)

※参考:【Express】Heroku CLIを使ってNode.js環境をHeroku上にデプロイする - クモのようにコツコツと

今回は自分が直近で取り組んでいるテーマであるExpressアプリと連携してみる。

アドオンを確認

まず、アプリにすでにアドオンが入っているか確認する。

※参考:https://devcenter.heroku.com/ja/articles/heroku-postgresql#heroku-postgres-1

ターミナルのcdコマンドでExpressアプリのフォルダに移動

cd /(パス)/node-js-getting-started

Herokuのアドオンが入っているか調べる。

heroku addons

結果、今はアドオンされてない。

No add-ons for app aqueous-mountain-80366.

Herokuのダッシュボードの右上のメニュー「Data」を開く。 f:id:idr_zz:20201015061253j:plain

今作られているDBの一覧が表示されているが、こちらにも「aqueous-mountain-80366」のDBはないようだ。 f:id:idr_zz:20201015061307j:plain

HerokuにDBを作成する

早速DBを作ってみる。下記のコマンド。最後にコロン:に続けてプラン名hobby-devを指定。

$ heroku addons:create heroku-postgresql:hobby-dev

ダッシュボードのDATAを見る。データベースが増えた!DB名は「postgresql-aerodynamic-98170」。 f:id:idr_zz:20201015061606j:plain

DBを開いてみる。中身はまだない。 f:id:idr_zz:20201015061843j:plain 「BILLING APP」でアプリ「aqueous-mountain-80366」と紐づいていることがわかる。

hobby-devプランとは(無料だが1万行まで)

hobby-devプランは無料。ただし1万行までしか書き込みができないようだ。

※参考:Choosing the Right Heroku Postgres Plan | Heroku Dev Center

これはアプリ単体ではなくアカウント全体の話らしい。


将来に備えて1万行超えたときの対応策を調べる。

※参考:Heroku postgresqlアドオンの無料プランで制限に達したとき | ikapblog

※参考:herokuのデータベースをリセット/リストア/再構築する - Qiita

※参考:MetabaseをHerokuで使って、10000行を超えて無料の限界が来たときの対処法 | Be full stack

削除前にバックアップを取ったり

※参考:Herokuでデータベースのバックアップを行いたい - Qiita

有料プランに移行して容量を増やしたり

※参考:PostgreSQL のプランを Free から Hobby に移行する(Heroku) - ブログ

アプリごとにアカウントを変えたり

※参考:heroku CLIで複数のアカウントを管理する | エンジニアもどきの技術メモ

DB情報を見る

下記のコマンドでHerokuのDB情報を見ることができる。

$ heroku pg:info

結果

=== DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            12.4
Created:               2020-10-12 19:55 UTC
Data Size:             7.9 MB
Tables:                0
Rows:                  0/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off

hobby-devプランでデータサイズは7.9MB。テーブルも行も0。などの状況がわかる。

DBに接続…できず。。

次にDBに接続するコマンド

$ heroku pg:psql

結果、んん?

--> Connecting to postgresql-aerodynamic-98170
 ▸    The local psql command could not be located. For help installing psql, see
 ▸    https://devcenter.heroku.com/articles/heroku-postgresql#local-setup

「 -> postgresqlへの接続-aerodynamic-98170
▸ローカルのpsqlコマンドが見つかりませんでした。 psqlのインストールについては、を参照してください。
▸https://devcenter.heroku.com/articles/heroku-postgresql#local-setup」

ふむ。psqlコマンドが見つからない(使えない)と。


参照先にあたる日本語チュートリアルを見る。

pg:psqlコマンドを使うにはPostgreSQLのインストールが必要とのこと。

​heroku pg:psql​ を使用するには、PostgreSQL が​システムにインストール​されている必要があります。

※参考:Heroku Postgres | Heroku Dev Center

公式からPostgreSQLインストール…できず。。

チュートリアルの「Postgres on Macの設定」を参考に進める。

※参考:Heroku Postgres | Heroku Dev Center

リンク先のPostgreSQL公式の「インストール手順」を参考に進める。

※参考:Postgres.app – the easiest way to get started with PostgreSQL on the Mac

ダウンロードページ f:id:idr_zz:20201015064510j:plain

※参考:Postgres.app Downloads

早速ダウンロードしてみるが64MBあって結構時間かかる。しかも自分の環境だとなぜか最後らへんで止まったりする!何度試みてもダメ。。

Homebrewを使ってPostgreSQLをインストール

他の方法を調べる。Homebrewを使ってインストールをしてみる。

※参考:初心者のMac + PostgreSQL インストール - Qiita

下記のコマンドでインストール。しばらく処理が続く…。

$ brew install postgresql

終わったらインストールされたか確認(バージョン表示)

$ postgres --version

結果、バージョンが表示された!

postgres (PostgreSQL) 12.4

PotgreSQL入った〜!

DBを起動する

続いてPostgreSQLサーバを起動するコマンド。

$ pg_ctl -D /usr/local/var/postgres start

※参考:https://www.postgresql.jp/document/9.1/html/app-pg-ctl.html

DBを一覧表示するコマンド

$ psql -l

※参考:https://www.postgresql.jp/document/9.3/html/app-psql.html

結果、DBの一覧表示された!!

                             List of databases
   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
-----------+----------+----------+---------+-------+-----------------------
 postgres  | (ユーザ名) | UTF8     | C       | C     | 
 template0 | (ユーザ名) | UTF8     | C       | C     | =c/(ユーザ名)          +
           |          |          |         |       | (ユーザ名)=CTc/(ユーザ名)
 template1 | (ユーザ名) | UTF8     | C       | C     | =c/(ユーザ名)          +
           |          |          |         |       | (ユーザ名)=CTc/(ユーザ名)
(3 rows)

PATHを通すコマンドの処理内容を調べる

これでリファレンスの2番目まで終わったことになる。次は3番目!

※参考:Postgres.app – the easiest way to get started with PostgreSQL on the Mac

Configure your $PATH to use the included command line tools (optional):

「付属のコマンドラインツールを使用するように$ PATHを構成します(オプション)。」

でた!PATHを通す!環境変数の設定のことね。

※参考:【Express】環境変数とは?PATHを通すとは?けっきょく南極ローカルインストール!(Herokuコマンドでローカル起動) - クモのようにコツコツと


下記のコマンドでできるようなんだが…

$ sudo mkdir -p /etc/paths.d &&
echo /Applications/Postgres.app/Contents/Versions/latest/bin | sudo tee /etc/paths.d/postgresapp

一見では処理内容がよくわからない。調べる。


まずsudoは最高権限者(スーパーユーザ)として実行(Do)することね。

※参考:Laravel元年!インストールしてMAMP環境で白い画面出す!! - クモのようにコツコツと

mkdir(ディレクトリ作成)のpオプションは「必要に応じで親ディレクトリを作成」という意味。

※参考:Linux mkdir コマンド - Qiita

&&は「Aが成功したらBを実行する」というコマンド

※参考:Linuxで「&&」を使うとコマンドのAND演算ができる

teeは「コマンドの結果をファイルに上書きする」というコマンド

「コマンドの結果をファイルに出力したいけど、標準出力でも出力を見たい!」

※参考:teeコマンドの使い方 - Qiita

ふぃー、ようやく処理のイメージができてきた。

PATHを通す

では、PATHを通すコマンドを実際に実行してみる。

$ sudo mkdir -p /etc/paths.d &&
echo /Applications/Postgres.app/Contents/Versions/latest/bin | sudo tee /etc/paths.d/postgresapp

sudoの実行のため、パスワードの入力を求められる。OSログイン時のパスワードを入れる。

Password:

結果、下記のパスが表示された!

/Applications/Postgres.app/Contents/Versions/latest/bin

PostgreSQL公式サイトによると

※参考:Postgres.app – the easiest way to get started with PostgreSQL on the Mac

Done! You now have a PostgreSQL server running on your Mac with these default settings:

「完了! これで、Mac上で次のデフォルト設定でPostgreSQLサーバーが実行されます。」

ローカルのPostgreSQLの接続情報は下記のような内容らしい。

項目
Host localhost
Port 5432
User your system user name
Database same as user
Password none
Connection URL postgresql://localhost

Postgres CLIのPATHを確認

次にチュートリアルの「2」、Postgres CLIツールのインストールを行う。

※参考:Heroku Postgres | Heroku Dev Center

リンク先になっているCLI Toolsのリファレンスを見ると…

※参考:Using Command Line Tools with Postgres.app

お、ここにもPATHを通すコマンドがある。さっきと同じ内容だ。

$ sudo mkdir -p /etc/paths.d &&
echo /Applications/Postgres.app/Contents/Versions/latest/bin | sudo tee /etc/paths.d/postgresapp

新しいターミナルを開いてPostgres CLIのPATHをwhichコマンドで確認する。

$ which psql

whichコマンドは環境変数のパスを表示するコマンド。

※参考:【 which 】コマンド――実行コマンドのフルパスを表示する:Linux基本コマンドTips(94) - @IT

結果、パスは出たがさっきと違うようだ。あっているのかな?

/usr/local/bin/psql

PATHにPostgres.app​が含まれない理由…調べ切れず。。

チュートリアルの「4」にはこうあるのだが…。

正しく機能したことを確かめます。OS X バージョンの ​psql​ は、​Postgres.app​ ディレクトリを含むパスを示している必要があります。

※参考:Heroku Postgres | Heroku Dev Center

表示されたパスには「​Postgres.app​」が含まれてない。。

「/usr/local/bin/psql」について調べると…

/usr/local/binは自分でインストールしたコマンドを使えるようにする場所みたいです。

※参考:/bin, /usr/bin, /usr/sbin, /usr/local/bin の違いとは? - Qiita

「​Postgres.app​」が含まれない理由を調べてもよくわからなかった。

which psqlの結果が/usr/local/binになる、と書かれている記事もある。

※参考:PSQL

こちらのQAはそのものずばりな内容のようだ。

※参考:database - Postgres.app setup: getting `which psql` to return desired path - Stack Overflow

exportコマンドで解決、とあったがリンク先のチュートリアルにexportコマンドの言及がないのがちょっと気になる。

※参考:Using Command Line Tools with Postgres.app

DBの動作確認

とりあえずチュートリアルの次の処理に進んで問題が生じるか確かめよう。

※参考:Heroku Postgres | Heroku Dev Center

データベースを作成する。

$ createdb

クラウド環境のHeroku上にはすでにDBはあるのだが、これはローカル環境にDBを作成するコマンドのようだ。

※参考:https://www.postgresql.jp/document/9.2/html/app-createdb.html

DBに接続する。

$ psql -h localhost

これもクラウドではなくローカルのDBに接続しているようだ。

-h hostname
--host=hostname
サーバを実行しているマシンのホスト名を指定します。 この値がスラッシュから始まる場合、Unixドメインソケット用のディレクトリとして使用されます。

※参考:https://www.postgresql.jp/document/9.2/html/app-psql.html

結果、DBに接続した!

psql (12.4)
Type "help" for help.

=# 

DBのバージョンとヘルプ表示の方法が出てる。そして頭の記号が$から=#に変わった。

DBを閉じるコマンドはこちら。

=# \q

頭の記号が$に戻った。

バイナリ、bin 、PATH、シェル…いろいろ調べる

さて、チュートリアル「Postgres on Mac の設定」の最後の段落を見ると…

※参考:Heroku Postgres | Heroku Dev Center

PostgreSQL には、使用したいと思えるような ​pg_dump​ や ​pg_restore​ などの複数の有用なバイナリが付属しています。Postgres.app を含んだ ​/bin​ ディレクトリを PATH に追加します (これがすべてのターミナルセッションに対して設定されるように、できれば ​.profile​、​.bashrc​、​.zshrc​ などで追加します)。

うーむ、まるまるわからん。。


わからない単語を一つずつ調べていこう。

pg_dump

PostgreSQLデータベースをスクリプトファイルまたは他のアーカイブファイルへ抽出する

※参考:https://www.postgresql.jp/document/9.2/html/app-pgdump.html

「アーカイブファイル」は圧縮ファイルのこと。

※参考:https://wa3.i-3-i.info/word11512.html

pg_restore

pg_dumpによって作成されたアーカイブファイルからPostgreSQLデータベースをリストアする

※参考:https://www.postgresql.jp/document/9.2/html/app-pgrestore.html

「リストア」はバックアップを復元すること。

※参考:https://wa3.i-3-i.info/word17817.html

バイナリ

コンピュータが扱うデータのうち、テキストデータ以外のデータ(バイナリデータ)のこと。

※参考:https://wa3.i-3-i.info/word14226.html

​/bin​ ディレクトリ

binとは、Binary codeのことでようするに実行可能プログラム置き場ということ。

※参考:Linuxの/bin、/usr/bin、$HOME/binのそれぞれの役割 - Qiita

「PATHに追加」は上にも書いたように環境変数を設定すること。そしてwhich psqlコマンドで「Postgres.app」はPATHに含まれてなかったんだよなー…。

ターミナルセッション

端末間での接続の単位のこと指す。ある端末から他の端末に接続し、データの送受信を行って、接続を切断するまでの一連の動作のこと。

※参考:ターミナルセッションとは - コトバンク

.profile

ログインシェルがbashで、かつ「.bash_profile」と「.bash_login」が無い状態でログインしたときに読み込まれる設定ファイル

※参考:https://wa3.i-3-i.info/word13652.html

「ログインシェル」とは?

ログインして最初に動き出すシェルのこと

※参考:https://wa3.i-3-i.info/word11274.html

「シェル」とは?

シェル (英語: shell) はオペレーティングシステム(OS)があるような高機能なコンピュータにおいて、ユーザーのためにインタフェースを提供するコンピュータプログラム

※参考:シェル - Wikipedia

「bash」とは?

shをパワーアップしたシェル

※参考:https://wa3.i-3-i.info/word11786.html

「.bash_profile」とは?

ログインシェルがbashの状態でログインしたときに読み込まれる設定ファイル

※参考:https://wa3.i-3-i.info/word13650.html

「.bash_login」とは?

ログインシェルがbashで、かつ「.bash_profile」が無い状態でログインしたときに読み込まれる設定ファイル

https://wa3.i-3-i.info/word13651.html

.bashrc

(ログインした後に画面上から)bashを起動したときに読み込まれる設定ファイル

※参考:https://wa3.i-3-i.info/word13649.html

.zshrc

ログインシェル、インタラクティブシェルの場合に読み込まれる

ログインシェル、インタラクティブシェル、シェルスクリプトの使い分け

  1. ログインシェル
    コマンドラインを起動したとき、サーバにログインしたときに立ち上がるシェルのこと
    対話形式で入力する

  2. インタラクティブシェル
    コマンドラインで bash とか zsh と入力すると起動するシェルのこと
    対話形式で入力する

  3. シェルスクリプト
    シェルによるプログラミングファイルを作成して実行すること

※参考:.zshenvと.zshrcの場所・違い・設定方法を解説します!

「zsh」とは?

Z shell(ズィーシェル、zsh)は、Unixのコマンドシェルの1つである。対話的なログインコマンドシェルとしても、強力なシェルスクリプトコマンドのインタープリターとしても使うことができる。

※参考:Z Shell - Wikipedia

要約すると「PostgreSQLにある便利な機能を使える様に、各種シェルの設定ファイルにPostgres.appを含むPATHを追加する」といったことかな。

PATHの追加(export)※実行は保留

上記の段落のあとに下記のコードが書かれている。

PATH="/Applications/Postgres.app/Contents/Versions/latest/bin:$PATH"

しかしターミナルでこれを打ってもで何も起こらない。

先ほどの段落の内容によればこれは「 ​.profile​、​.bashrc​、​.zshrc​」などのシェルの設定ファイルに書くべき内容と思われる。

シェルのパス追加方法を調べるとexportコマンドを使うようだ。

~/.bashrcや~/.bash_profileに以下のコマンドを記述する。(記述はどちらかで良い。)

export PATH=$PATH:追加したいコマンド検索パス

※参考:PATHを通すために環境変数の設定を理解する (Mac OS X) - Qiita

あと、$PATHコマンド検索パスの順番も逆になっているのもよくわからない。

exportコマンドは先ほどのQAにもあった!)

※参考:database - Postgres.app setup: getting `which psql` to return desired path - Stack Overflow

実際、自分の環境のユーザー直下のある.bash_profileを開いたらexportコマンドを使った設定が書かれていた。

この時点ではexportコマンドでPATHを追加するはちょっと怖かったので一旦ペンディング。

PATHの確認(echo)

先ほどの記事にechoコマンドでPATHの値が確認する方法も書かれていた。

※参考:PATHを通すために環境変数の設定を理解する (Mac OS X) - Qiita

確認してみる。

echo $PATH

結果、いろいろ表示された!

/Applications/Postgres.app/Contents/Versions/latest/bin:/Users/(ユーザ名)/.npm-global/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

値は複数設定できて、コロン:で区切られている。そして左から優先されるらしい。

つまりこういうことか

/Applications/Postgres.app/Contents/Versions/latest/bin:
/Users/(ユーザ名)/.npm-global/bin:
/usr/local/bin:
/usr/bin:
/bin:
/usr/sbin:
/sbin

これを見るとPostgres.appが含まれる値が最優先になっているようだ。問題ない、ということでいいのかな…?


なお、PATHの値の優先順位を変える処理はこう書く。

export PATH=追加したいコマンド検索パス:$PATH

コマンド検索パス$PATHの順番はこちらの方が似ている!(しかし頭にexportコマンドはやはり必要)


また、.bashrc.bash_profileの違い、使い分けについてはこちらが参考になった。

  • ログイン時に一回だけ実行したい時
    -> .bash_profileに記載
  • シェルを起動する度に実行したい時(一般的な設定)
    -> .bashrcに記載

※参考:.bash_profileと.bashrcについて - Qiita

PATHについては前提知識が足りな過ぎてキリがないので、ここらで一区切りにしておく。全体像のイメージはできた。

Heroku CLI​でPostgreSQLに接続(pg:psql)

先ほどつまづいたHeroku CLI​でのPostgreSQLでの接続にリベンジ!

※参考:Heroku Postgres | Heroku Dev Center

pg:psqlコマンドを実行

heroku pg:psql

結果、おおぉ!接続したようだ!!

--> Connecting to postgresql-aerodynamic-98170
psql (12.4)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

aqueous-mountain-80366::DATABASE=> 

行頭が$からDATABASE=>に変わった。

事例ではSELECT文を実行しているが…

DATABASE=> SELECT * FROM users;

結果は「users」が見つからないと。

ERROR:  relation "users" does not exist
LINE 1: SELECT * FROM users;

まあそうだよな。まだ何も作ってないからw

チュートリアルには停止方法が見当たらなかったがこちらの\qで停止できた。

DATABASE=> \q

※参考:Heroku PostgresのDBにターミナルからアクセスする - Qiita

先ほどのローカルDBを閉じるコマンド=# \qと共通だった。

最後に

ということでHerokuのPostgreSQLに接続することができました。

  • アドオンを確認
  • HerokuにDBを作成
  • DB情報を見る
  • Homebrewを使ってPostgreSQLをインストール
  • DBを起動
  • PATHを通す
  • DBの動作確認
  • Heroku CLI​でPostgreSQLに接続

本当はCRUD処理くらいまで行きたかったのですが、内容が膨らんだためいったんここで区切ります。

ここに至るまで結構何日もかかって、自分としては難産でした。わからないことを調べて、その中にまたわからないことがあって…という数珠繋ぎ状態で自分の前提知識の少なさが身に染みました。。

次回はPostgreSQLでテーブルを作って、SQL文(CRUD処理)にトライします!

それではまた!


※参考:Web開発環境についてのまとめ
qiita.com