0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[02] SQLite3 を PostgreSQL へ置き換える

Last updated at Posted at 2021-07-12

はじめに

Docker (docker-compose)と Linux に標準で搭載されているシェルを組み合せて、
下記 概要に挙げた Django 環境を 1コマンドで即座に立ち上げるためのコードとその解説です.

本記事の内容は、Zenn で書籍として販売している内容と同一です.
Zenn でも書籍の内容は全て無料公開しています.

次の順でコードを作成してください.
動作するコードが作成できるように可能な限り注意を払って執筆しました.

[01] デフォルト環境 runserver + SQLite3 の構築
・本記事の内容

概要

今回は下図・下表の環境を構築する. (前章からの変更点は🔥である)
具体的には次の通り.
・SQLite3 ではなく、PostgreSQL を使うようにする

概念図

image.png

コンテナ内の構成

項目 補足
Python バージョン3.8.3 python:3.8.3-slim-buster を使う
Django バージョン3.0.7
アプリサーバ runserver 8000番ポートを使用する
データベース PostgreSQL 12.0🔥 ポートは次の通り
・ホスト側「53432」
・コンテナ側「5432」
管理者アカウントは次の通り
・アカウント「admin
・パスワード「admin
settings.py DATABASE」の設定を PostgreSQL に変える. 🔥 ホスト上の ./web/assets/settings.py が、
コンテナ内に /usr/src/app/config/settings.py として配置される.
Django admin ページ 管理者アカウントは次の通り
・アカウント「admin
・パスワード「admin

セットアップコード

全文

前章で作成したコードに対して、本記事の内容を適用してください.

web/assets/settings.py より、「DEBUG = True」のみセットアップできることを確認している.

ファイル構成

上記 GitHub からコードを取得してきた直後の構成である.
前章から変更が生じたファイルには🏷️を、新規作成については🆕を付与している.

$ tree . --charset=c -a
.
|-- db 🆕
|   `-- Dockerfile 🆕
|-- docker-compose.yml 🏷️
|-- setupapp.sh 🏷️........... セットアップスクリプト
`-- web
    |-- Dockerfile 🏷️
    `-- assets .............. コンテナへコピーされるデータ
        |-- entrypoint.sh 🏷️
        |-- requirements.txt 🏷️
        `-- settings.py 🏷️

解説

db/Dockerfile

新規作成.
特筆すべき事項なし.

FROM postgres:12-alpine
ENV LANG ja_JP.utf8

## プロキシサーバを使う場合
# ENV http_proxy="http://proxy.co.jp:8080"	
# ENV https_proxy="http://proxy.co.jp:8080"

# 時刻を日本に合わせる
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

setupapp.sh

前章からの変化点は次の通り.
・PostgreSQL 用の永続化ボリュームとして次を作成する.
   ./db/data
   ./db/init

・PostgreSQL を使用するよう記述した settings.py をコンテナ内に配置する

以下、前回からの差分である.

--- ./setupapp.sh.ORIG
+++ ./setupapp.sh
@@ -2,6 +2,8 @@
@@ -2,6 +2,8 @@
 
 # 旧データを削除する
 sudo rm -rf web/app
+sudo rm -rf db/data
+sudo rm -rf db/init
 
 # docker-compose.yml で書かれたサービスのコンテナ、イメージ、ネットワークを削除する
 docker-compose down --rmi all --volumes
@@ -11,9 +13,13 @@
 
 # 必須ディレクトリを作成する
 sudo mkdir -p web/app
+sudo mkdir -p db/data
+sudo mkdir -p db/init
 
 # entrypoint.sh を配置する
 sudo cp ./web/assets/entrypoint.sh ./web/app/
+# settings.py をコンテナ内に .settings.py として配置する
+sudo cp ./web/assets/settings.py ./web/app/.settings.py
 
 # Dockerイメージビルドを行う. 
 docker-compose build
@@ -31,6 +37,9 @@
 }
 
 # コンテナ内でのマイグレーション終了を待つ.
+# なお、ここで 待機時間を取らないと次のエラーが出現してしまう.
+#「django.db.utils.IntegrityError: duplicate key value violates unique constraint "pg_type_typname_nsp_index"」
+# [参考] https://www.odin.hyork.net/write/write0206.html
 sleep 4
 
 # 「Django管理サイト」の管理者アカウントを作成する. (ID「admin」, PW「admin」とする)

docker-compose.yml

前章からの変化点は次の通り.
・ポート (ホスト側 : コンテナ側) = (53432 : 5432) とする.
・PostgreSQL の管理者アカウント「admin」、パスワード「admin」とする

--- docker-compose.yml.ORIG
+++ docker-compose.yml
@@ -11,3 +11,19 @@
       - ./web/app/:/usr/src/app/
     ports:
       - 8000:8000
+    depends_on:
+      - db
+  db:
+    build: ./db
+    image: postgres:12
+    container_name: mypostgres12
+    volumes:
+        - ./db/data:/data
+        - ./db/init:/docker-entrypoint-initdb.d/
+    ports:
+        - "53432:5432"
+    environment:
+        POSTGRES_DB: 'django307'
+        POSTGRES_USER: 'admin'
+        POSTGRES_PASSWORD: 'admin'
+        PGDATA: '/data'

web/Dockerfile

前章からの変化点は次の通り.
・build-essential は requirements.txt に追加した psycopg2 のインストールで必要である
・libpq-dev は Python から PostgreSQL を操作するために必要である

--- web/Dockerfile.ORIG
+++ web/Dockerfile
@@ -11,6 +11,10 @@
 ENV PYTHONDONTWRITEBYTECODE 1
 ENV PYTHONUNBUFFERED 1
  
+RUN apt-get update
+RUN apt-get install -y build-essential
+RUN apt-get install -y libpq-dev
+
 # 時刻を日本に合わせる
 RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

web/assets/entrypoint.sh

前章からの変化点は次の通り.
・事前に PostgreSQL の設定を記述しておいた settings.py を、コンテナ内の /usr/src/app/config/settings.py として配置する

--- web/assets/entrypoint.sh.ORIG
+++ web/assets/entrypoint.sh
@@ -4,6 +4,8 @@
 test ! -f manage.py && { 
   # プロジェクトを作成する (config/ と manage.py が作成される)
   django-admin.py startproject config .
+  # 事前に用意しておいた PostgreSQL 対応の settings.py に差し替える
+  cp -f .settings.py config/settings.py
   # マイグレーションを実施する
   python manage.py makemigrations
   python manage.py migrate auth

web/assets/requirements.txt

前章からの変化点は次の通り.
・Python から PostgreSQL を操作するために psycopg2 と psycopg2-binary の 2パッケージをインストールする

--- web/assets/requirements.txt.ORIG
+++ web/assets/requirements.txt
@@ -2,3 +2,5 @@
 django-extensions==2.2.9
 django-filter==2.2.0
 djangorestframework==3.11.0
+psycopg2==2.8.5
+psycopg2-binary==2.8.5

web/assets/settings.py

前章からの変化点は以下である.
なお、前章では Django が生成するデフォルトの settings.py を使用していた.
・PostgreSQL の記述を追加した.
・PostgreSQL の管理者アカウントとパスワードはともに「admin」としている.
・使用する Database 名は「django307」としている.

--- ./web/assets/settings.py.ORIG
+++ ./web/assets/settings.py
@@ -75,8 +75,12 @@
 
 DATABASES = {
     'default': {
-        'ENGINE': 'django.db.backends.sqlite3',
-        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+        'ENGINE': 'django.db.backends.postgresql',
+        'NAME': 'django307',
+        'USER': 'admin',
+        'PASSWORD': 'admin',
+        'HOST': 'db',
+        'PORT': 5432,
     }
 }

セットアップ方法

次の通りコマンドを実行する.

$ ./setupapp.sh

セットアップ後

ファイル構成

.
|-- db
|   |-- Dockerfile
|   |-- data [error opening dir]
|   `-- init
|-- docker-compose.yml
|-- setupapp.sh
`-- web
    |-- Dockerfile
    |-- app
    |   |-- config
    |   |   |-- __init__.py
    |   |   |-- asgi.py
    |   |   |-- settings.py
    |   |   |-- urls.py
    |   |   `-- wsgi.py
    |   |-- entrypoint.sh
    |   `-- manage.py
    `-- assets
        |-- entrypoint.sh
	|-- requirements.txt
        `-- settings.py

動作確認方法

次の点を確認すれば良い.

✔ Dockerコンテナが次のように起動していること

$ docker-compose ps
    Name                  Command               State            Ports         
-------------------------------------------------------------------------------
mydjango307    /usr/src/app/entrypoint.sh ...   Up      0.0.0.0:8000->8000/tcp 

http://localhost:8000 にアクセスして次の画面が表示されること.

image.png


http://localhost:8000/admin にアクセスして、アカウント「admin」、パスワード「admin」でログインできること.

image.png


✔ ./web/app/db.sqlite3 が存在していないこと

もしも存在している場合は、settings.py が正しく配置できていない疑いがある.


✔ PostgreSQL コンテナにて Database にログインできること

次のパラメータで PostgreSQL のデータベース「django307」にログインする

項目
アカウント admin
パスワード admin
ポート 5432番
データベース django307
$ docker-compose exec db bash -c 'PGPASSWORD=admin psql -U admin -h db -p 5432 -w django307'

そして、次のように「データベース」一覧が表示されれば良い

django307-# \l
                                     データベース一覧
   名前    | 所有者 | エンコーディング |  照合順序  | Ctype(変換演算子) |  アクセス権限   
-----------+--------+------------------+------------+-------------------+-----------------
 django307 | admin  | UTF8             | ja_JP.utf8 | ja_JP.utf8        | 
 postgres  | admin  | UTF8             | ja_JP.utf8 | ja_JP.utf8        | 
 template0 | admin  | UTF8             | ja_JP.utf8 | ja_JP.utf8        | =c/admin       +
           |        |                  |            |                   | admin=CTc/admin
 template1 | admin  | UTF8             | ja_JP.utf8 | ja_JP.utf8        | =c/admin       +
           |        |                  |            |                   | admin=CTc/admin
(4 行)


以上.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?