【Django】AWSでPostgresqlとの連携

django-logo

題目どおりにAWS上でDjangoをPostgresqlに繋ぐためのフローをまとめています。

あまり説明はしませんが、どのように作成すればいいかの指針になるといいなと思います。

実行環境

今回使用するのはcloud9を使います。使用するのはAmazon Linuxです。

まっさらな環境から構築いたします。

環境は以下になります。

FSE:~/environment $ uname -a
Linux ip-172-31-32-133 4.14.123-86.109.amzn1.x86_64 #1 SMP Mon Jun 10 19:44:53 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

また、その他の環境は以下でした。

(project_db) FSE:~/environment/project_db $ psql --version
psql (PostgreSQL) 9.2.24
(project_db) FSE:~/environment/project_db $ django-admin --version
2.2.3

Postgresqlの準備

まずは、postgresqlの環境を整えます。

以下のコマンドでpostgresqlをインストールとしてください

sudo yum -y install postgresql postgresql-server

インストールできたことを確認するために以下のコマンドでバージョンを確認しましょう。

FSE:~/environment $ psql --version
psql (PostgreSQL) 9.2.24

Postgresqlのサーバーを立ち上げる

Postgreは使用する前に初期化する必要があります。
以下のコマンドを実行してください。

FSE:~/environment $ sudo service postgresql initdb
Initializing database:                                     [  OK  ]

Postgreサーバーを立ち上げましょう。
以下のコマンドを実行してください。

FSE:~/environment $ sudo service postgresql start
Starting postgresql service:                               [  OK  ]

正常に立ち上がったことを確認するためにログインしてみましょう。
以下のコマンドで確認してください。

sudo -u postgres psql -U postgres
could not change directory to "/home/ec2-user/environment"
psql (9.2.24)
Type "help" for help.

postgres=# 

postgresのコマンドプロンプトがでているので成功になります。

Postgresqlでユーザ登録

Postgresqlの初期設定ではpeer認証となっていますので、ec2-userのロール及びDBがないとpostgresユーザを使わなければなりません。

以下のコマンドでec2-userを作成してください.

FSE:~/environment $ sudo -u postgres createuser ec2-user
could not change directory to "/home/ec2-user/environment"

さらにPostgresqlではユーザ名と同じDBが必要になります。
以下のコマンドでec2-userというデータベースを作ります。

FSE:~/environment $ sudo -u postgres createdb ec2-user -O ec2-user
could not change directory to "/home/ec2-user/environment"

-Oはオプションで、データベースの所有者を指定します。今回はec2-userにしています。

それでは、ユーザーが作成できていたのかを確認します。


FSE:~/environment $ psql
psql (9.2.24)
Type "help" for help.

ec2-user=> select * from pg_user;
 usename  | usesysid | usecreatedb | usesuper | usecatupd | userepl |  passwd  | valuntil | useconfig 
----------+----------+-------------+----------+-----------+---------+----------+----------+-----------
 postgres |       10 | t           | t        | t         | t       | ******** |          | 
 ec2-user |    16389 | f           | f        | f         | f       | ******** |          | 
(2 rows)


ec2-userが登録されていることが確認できますね。
終了するには、「\q」もしくはCtrl + Dを押してください

それではDBが作成されているかを確認します。


FSE:~/environment $ psql -l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 ec2-user  | ec2-user | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(4 rows)


ec2-user というデータベースが正常に作成されていますね。

もしdjangoで別のユーザとデータベースを作成する場合は同様にユーザーとデータベースを作成します。

今回は以下のように設定しています。


sudo -u postgres createuser test_user
sudo -u postgres createdb test_db -O test_user

ユーザのパスワードを設定する

認証方式を変更する前にユーザにパスワードを設定しておきましょう。

これも権限が必要なのでpostgresとしてpsqlを起動しています。


FSE:~/environment $ sudo -u postgres psql
could not change directory to "/home/ec2-user/environment"
psql (9.2.24)
Type "help" for help.

postgres=#

ユーザのパスワードを設定しましょう。


postgres=# ALTER USER test_user  WITH ENCRYPTED PASSWORD 'test_password';
ALTER ROLE

上記ではtest_userに対してtest_passwordを設定しています。

ここで設定したユーザー名とパスワード及び、DB名はDjangoで使用しますので覚えて起きましょう。

Postgresqlの認証方式を変更する

認証方式を変更するには、pg_hba.confのファイルの内容を変更する必要が有ります。

まずは、そのファイルの場所を調べましょう。
以下のコマンドを実行してください。

FSE:~/environment $ sudo -u postgres psql -q
could not change directory to "/home/ec2-user/environment"
postgres=# show hba_file;
             hba_file             
----------------------------------
 /var/lib/pgsql9/data/pg_hba.conf
(1 row)


私の場合は/var/lib/pgsql9/data/pg_hba.confにあるようです。

それでは編集のために以下を入力してください

sudo vi /var/lib/pgsql9/data/pg_hba.conf

このファイルを編集するためには権限が必要ですので、必ずsudoを付けてください。

ファイルの下のほうに以下のような記述が有ります。


# IPv4 local connections:
host    all             all             127.0.0.1/32            ident

以下のように変更してください。
identtrustにしています。


# IPv4 local connections:
host    all             all             127.0.0.1/32            md5

設定ファイルを変更したのでサーバーを再起動します。

FSE:~/environment $ sudo service postgresql restart
Stopping postgresql service:                               [  OK  ]
Starting postgresql service:                               [  OK  ]

Djangoをインストールする

まずはプロジェクトとなるディレクトリを作り、移動します。

FSE:~/environment $ mkdir project_db && cd project_db
FSE:~/environment/project_db $ 

pipのバージョンを上げておきます。

FSE:~/environment/project_db $ sudo pip-3.6 install --upgrade pip

pipenvをインストールします。
私の場合は権限によるエラーが出たので–userオプションを指定しています。


FSE:~/environment $ pip3 install pipenv --user

pipenvでdjangoをインストールします。


FSE:~/environment/project_db $ pipenv install django==2.2.3

pipenvを起動します。

FSE:~/environment/project_db $ pipenv shell
Launching subshell in virtual environment…
FSE:~/environment/project_db $  . /home/ec2-user/.local/share/virtualenvs/project_db-ixZ6iYXw/bin/activate
(project_db) FSE:~/environment/project_db $ 

pipenvを起動すると左側でディレクトリを丸括弧で囲んで表示されるので、分かりやすくなっています。

Djangoプロジェクトの設定

それではDjangoのプロジェクトを作成します。
最後のドットに気をつけてください。

(project_db) FSE:~/environment/project_db $ django-admin startproject db_connection . 

ちなみにドットがあると、プロジェクトファイルを作成せずにその場でファイルを展開します。

以下のコマンドで設定ファイルをいじります。

(project_db) FSE:~/environment/project_db $ vi db_connection/settings.py 

設定を変更する場所は2点あります。
ALLOWED_HOSTSとDATABASESです。それぞれ見ていきましょう。

ALLOWED_HOSTS

初期値だと[]になっています。

ローカル接続の場合は[]で大丈夫ですが、cloud9の場合は状況が違います。
接続できるように、指定してあげましょう。

よく分からない人は以下でも大丈夫です。

ALLOWED_HOSTS = ['*']

DATABASES

初期設定ではsqlite3をdjangoは使用します。

従って、ここをpostgresql用に変更します。
初期設定は以下になります。


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


上記を以下に変更します。


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'test_db', #DB名 
        'USER': 'test_user', #USER名
        'PASSWORD': 'test_password', #PASSWORD
        'HOST': 'localhost', #接続HOST
        'PORT': '5432', #接続ポート 省略可
    }
}


Djangoを起動

最後にPythonがpostgresqlにアクセスするためのモジュールとしてpsycopg2-binaryをインストールします。

(project_db) FSE:~/environment/project_db $ pip install psycopg2-binary

それではDjangoをマイグレートしましょう!

(project_db) FSE:~/environment/project_db $ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

成功しましたね。

それでは最後にサーバーを立ち上げて、画面を表示してみましょう。

(project_db) FSE:~/environment/project_db $ python3 manage.py runserver 8080

晴れて、DBに接続してDjangoが使えるようになりました!

注意点・Tips

psycopg2

psycopg2は2.8からリネームしてpsycopg2-binaryになっていることに注意してください。

これに気づかず嵌りました。

まとめ

djangoの設定自体はそんなに難しくないと思います。ただ、postgresqlのサーバーの立ち上げやユーザーの作成が意外にめんどくさいことがわかりました。

ec2-userを作成したのは、psqlコマンドでいちいちアクセスできないのが面倒だったからです。権限を追加すればsudoコマンドは必要なくなると思います。

以上になります。

長々とお付き合いありがとうございました!