DjangoにPostgreSQLを適用する

# はじめに

Djangoの初期設定ではデータベースがSQLiteになっていますが、ここではPostgreSQLに変更します。

前提として、以下の作業を進めてきたものとします。
- [pyenvとvirtualenvをインストールする](http://qiita.com/shigechioyo/items/198211e84f8e0e9a5c18)
- [mod_wsgiでhello worldを描画する](http://qiita.com/shigechioyo/items/2b25f60918be6b81581a)
- [Djangoでhello worldを描画する](http://qiita.com/shigechioyo/items/b7980e4f5dc62c51d2cb)

あまり需要はなさそうですが、下記の環境でDjangoを設定する際に一連の流れが分かる日本語記事が見つからなかったため、 Hello World を描画するテーマでメモを残しています。


# 環境

OS: Debian 9.0 stretch
Python: 3.6.3
Django: 2.1.5

# PostgreSQLとツールのインストール
PostgreSQLとそれに必要なツール群のインストールです。

```bash
sudo apt update
sudo apt install -y python3-pip python3-dev libpq-dev postgresql postgresql-contrib
```

ここで、本当にインストールされたのかを一応確認しておきます。

```bash
psql --version
# ↓インストールしたバージョンが表示されれば成功です
psql (PostgreSQL) 9.6.10
```

インストールされていることと同時に、バージョンを確認しました。
そしてもう一つ、 postgres というユーザーが作成されています。これを確認してみます。

```bash
cat /etc/passwd
# 色々なユーザーが表示される中にpostgresがあるばずです。
postgres:x:107:113:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
```

このユーザーはPostgreSQLの管理ユーザーですので削除しないように注意してください。

# データベースの作成
早速、Djangoプロジェクトで使用するデータベースを作成します。
まずはPostgresセッションを開始します。

```bash
sudo -u postgres psql
```

するとこのような```postgres=#```表示と共にセッションが開始されているはずです
データベースを作成しましょう。ここではmyappというデータベースを作成します。

```sql
CREATE DATABASE myapp;
```

CREATE DATABASE と表示されればデータベースの作成は成功です。


# データベースユーザーを作成する
次に、データベースへ接続するユーザーを作成します。 ここではユーザー名を *USENAME* とし、パスワードを *PASSWORD* としています。

```sql
CREATE USER USERNAME WITH PASSWORD 'PASSWORD';
```

これは CREATE ROLE と表示されれば作成は完了です。
続けて、3つの設定を変更します。
これは主にDjangoの推奨設定への対応と、タイムゾーンの変更です。

```sql
ALTER ROLE USERNAME SET client_encoding TO 'utf8';
ALTER ROLE USERNAME SET default_transaction_isolation TO 'read committed';
ALTER ROLE USERNAME SET timezone TO 'Asia/Tokyo';
```

最後に、作成したユーザーに対してテーブルに対する接続権利を与えてセッションを終了します。

```sql
GRANT ALL PRIVILEGES ON DATABASE myapp TO USERNAME;
```

ちなみに、```\q```で終了します。

# パスワード認証へ変更する
現時点では、Peer認証という認証方式が設定されています。
これをパスワードでの認証へ変更します。
設定ファイルは```/etc/postgresql/9.6/main```下に存在する pg_hba.conf ファイルです。
ただし、お分かりかと思いますが 9.6とはバージョン名ですので、上で確認したバージョンに合わせて変更してください。
ここではバージョンが　9.6だと仮定して進めます。

```bash
cd /etc/postgresql/9.6/main
sudo vim pg_hba.conf
```

localから始まる行を探し、Peerをmd5に変更します。
つまり

```
local   all     all     peer
```

という項目を

```
local   all     all     md5
```

に変更です。

変更後はPostreSQLの再起動を行います

```bash
sudo /etc/init.d/postgresql restart
psql -U USERNAME -d myapp
```

これでmyappに接続ができるはずです。
確認したら```\q```で終了してください。

# Djangoの設定を変更する
ここまできたら、Djangoのデータベース設定を変更します。
しかし、その前に *psycopg2* をインストールします。なお、virtualenvを使用している場合は使用したい環境内へ移動することを忘れないでください。

```bash
pip install psycopg2-binary
```

Djangoの settings.py を変更します。
ここでは *myproject* というDjangoプロジェクトを作成していたものとして話を進めます。

```bash
cd ~/myproject/myproject
vim settings.py
```

開かれた settings.py の中にこのような箇所があるはずです。

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

これがデータベース設定部分です。
これを以下のように変更します。

```py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'myapp',
        'USER': 'USERNAME',
        'PASSWORD': 'PASSWORD',
        'HOST': 'localhost',
        'PORT': '',
    }
}
```

これで設定は完了です。
初回のマイグレートを行います。

```bash
cd ~/myproject
python manage.py makemigrations
python manage.py migrate
```

# スーパーユーザーの作成
マイグレーションが完了したところで、スーパーユーザーを作成して作業を終えます。
manage.py が存在するディレクトリに移動して```createsuperuser```を実行します。
すると、ユーザー名やパスワードなどを聞かれるので、任意のものを設定してください。

```bash
cd ~/myproject
python manage.py createsuperuser
Username (leave blank to use 'USERNAME'): 
Email address: example@example.co.jp
Password: 
Password (again): 
Superuser created successfully.
```

successfully が見えたら成功です。

では、本当に作成されたのかを二つの方法で確認します。

### - Django管理者画面にログインしてみる
[Djangoでhello worldを描画する]()で WSGIScriptAliasを設定しています。
この設定の通りにしていれば、
**(ドメイン名またはIPアドレス)/admin** にアクセスすることでログイン画面が表示されるはずです。
ここに先ほど設定したユーザー名とパスワードを入力することで、管理画面にログインできます。

### - データベースの内容を確認する
そもそも、 **本当にPostgreSQLにDjangoの情報が保存されているのか** という疑問があると思います。
では、データベースにアクセスしてみましょう。パスワードは **データベースユーザーを作成する** で設定したものです。

```bash
psql -U USERNAME -d myapp
Password:PASSWORD
```

無事接続できていれば、```myapp=>```という表示されます。
その後、ユーザーが本当に登録されているか、以下のSQLでテーブルを確認してみましょう。
(```myapp=>```は打ち込まないでくださいね)

```bash
myapp=> select * from auth_user;
```

これでテーブル内に先ほど登録したユーザーの存在を確認できるはずです。
なお、テーブルの一覧は```\d```で表示できます。
以上を終えたら```\q```でログアウトして終了です。