AI can fly !!

AI がやりたい Web エンジニアのアウトプット (AI の知識は無い)

【Django3.0】開発環境構築から初期設定まで【Python3.8】

django-logo

はじめに

Django で開発を行うにあたり、開発環境の構築からプロジェクトの初期設定など、ビジネスロジックの実装以外で基本的に一度やったらそれで終わりの作業をまとめました。

「えーと、 Django のプロジェクト作るには何をすればよかったんだっけ…」「あー!あの設定漏れてた!」と、僕がなることのまとめです。

新規に Django プロジェクトとアプリケーションを作成し、開発用の Web サーバを起動して Web ブラウザに Hello Django !! と表示するところまでをまとめました。

動作環境

OS Version
Windows 10 Pro 1909
Application Version
PowerShell 5.1.18362.752
Language Version
Python 3.8.1
Package Version
Django 3.0.4

開発環境構築

まずは、必要なパッケージのインストールやプロジェクトの作成から。

Python 仮想環境作成

最初に Python の仮想環境を作成します。

python -m venv venv

インストール

次に仮想環境へ切り替えを行い、 Django をインストールします。

./venv/Scripts/activate

pip install django

プロジェクト作成

インストールが完了したら、 Django のプロジェクトを作成します。

プロジェクトディレクトリを作成する場合

django-admin startproject [project_name]

カレントディレクトリにプロジェクトディレクトリが作成され、その中に Django アプリケーションの各構成ファイルが作成されます。

カレントディレクトリ = プロジェクトディレクトリの場合

django-admin startproject [project_name] .

カレントディレクトリに Django アプリケーションの各構成ファイルが作成されます。

アプリケーション作成

次に、プロジェクトルート直下にアプリケーションを作成します。

アプリケーション作成コマンドは、プロジェクトルートで実行します。

python manage.py startapp [application_name]

Django 初期設定

開発環境の構築が完了したら、プロジェクトの初期設定を行います。

プロジェクト

Django プロジェクトに関する設定は、プロジェクトディレクトリ内の設定ファイル (settings.py) で行います。

設定ファイル (settings.py)

[project_root]/[project_name]/settings.py

言語 (LANGUAGE_CODE)

-- LANGUAGE_CODE = "en-us"
++ LANGUAGE_CODE = "ja"

タイムゾーン (TIME_ZONE)

-- TIME_ZONE = "UTC"
++ TIME_ZONE = "Asia/Tokyo"

データベース (DATABASES)

   DATABASES = {
       "default": {
--     "ENGINE": "django.db.backends.sqlite3",
--     "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
++     "ENGINE": "django.db.backends.oracle",
++     "NAME": "[host]:[port]/[db_name].[db_domain]",
++     "USER": "[user]",
++     "PASSWORD": "[password]",
    }
}

Django では複数のデータベースを公式にサポートしており、ここでは例として Oracle Database への接続方法を記載しています。

テンプレート (TEMPLATES)

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

APP_DIRSTrue にすると、各アプリケーションディレクトリ直下の templates ディレクトリ内にあるテンプレートを参照する。

APP_DIRS のデフォルト値は True なので、特に変更の必要はありません。

インストールアプリケーション (INSTALLED_APPS)

   INSTALLED_APPS = [
++     "[application_name].apps.[AppConfig]",
       "django.contrib.admin",
       "django.contrib.auth",
       "django.contrib.contenttypes",
       "django.contrib.sessions",
       "django.contrib.messages",
       "django.contrib.staticfiles",
   ]

作成したアプリケーションの AppConfigINSTALLED_APPS に追加し、アプリケーションを有効化します。

プロジェクトに含めるアプリケーションは INSTALLED_APPS に追加する必要があり、逆に言えばここに追加しなければマイグレーション等の対象にはなりません。

プロジェクト作成時に既にいくつかのアプリケーションが追加されていますが、不要なものがあれば削除しても問題ありません。

ルーティング (urls.py)

URLconf で URL パターンをビューにマッピングします。

プロジェクトルート直下の URLconf では、主に各アプリケーションの URLconf への参照設定を行います。

[project_root]/[project_name]/urls.py
   urlpatterns = [
       path("admin/", admin.site.urls),
++     path("[application_name]/", include("[application_name].urls")),
   ]

プロジェクトルートから作成したアプリケーションまでのルーティングを追加する。

アプリケーション

ここからはアプリケーションディレクトリ内の各構成ファイルについてです。

ビュー (views.py)

Django のビューは、関数ベースとクラスベース (汎用ビュー) の二種類存在しますが、ここでは関数ベースのビューを例示しています。

[project_root]/[application_name]/views.py
   from django.shortcuts import render

++ def index(request):
++     context = {"framework": "Django"}
++     return render(request, "[application_name]/index.html", context)

ビューの役割は、データベースからのデータ取得やテンプレートのロード、レンダリングしたテンプレートの返却など多岐にわたります。

主なビジネスロジックはビューに実装することになります。

テンプレート (templates ディレクトリ)

[project_root]/[application_name]/templates/[application_name]/

プロジェクト設定ファイル (settings.py) の TEMPLATES.APP_DIRSTrue にした場合、アプリケーションディレクトリ直下の templates ディレクトリ内が参照されます。

templates ディレクトリ直下にテンプレートファイルを置かず、 [application_name] ディレクトリを作成してから、その中にテンプレートファイルを配置します。

テンプレートの名前空間 - Django チュートリアルより要約

Django では名前がマッチした最初のテンプレートを使用するので、異なるアプリケーションの中に同じ名前のテンプレートがあった場合、それらを区別することができません。

templates ディレクトリ直下に [application_name] サブディレクトリを作り、その中にテンプレートファイルを配置することで、名前空間を作成することができます。

Django にはテンプレート内で使用できる独自のテンプレート言語が存在します。

ここで例示しているテンプレートは、ビューから渡されたコンテキスト変数の framework の値を展開し、レンダリングされます。

[project_root]/[application_name]/templates/[application_name]/index.html
++ <!DOCTYPE html>
++ <html lang="ja">
++ <head>
++   <meta charset="utf-8">
++   <title>Django Application</title>
++ </head>
++ <body>
++   Hello {{ framework }} !!
++ </body>
++ </html>

ルーティング (urls.py)

アプリケーション作成コマンドでは、アプリケーションディレクトリに URLconf (urls.py) は作成されないため、自分で作る必要があります。

[project_root]/[application_name]/urls.py
++ from django.urls import path

++ from . import views

++ app_name = "[application_name]"
++ urlpatterns = [
++     path('', views.index, name='index'),
++ ]

プロジェクトルートの URLconf から渡された URL パターン (URL からプロジェクトルートの URLconf で定義された URL パターンを除いた文字列) と、ビューをマッピングします。

モデル (models.py)

[project_root]/[application_name]/models.py

Django では、データベースのテーブルを Python のクラスで表現し、カラムをクラス変数として定義します。

テーブルとクラスが一対一で紐づき、これが一つのモデルとなります。

今回は Hello Django !! と表示するだけなのでモデルは必要ありませんが、モデルの簡単な書き方だけ例示します。

from django.db import models

class [class_name](models.Model):
    [column_name_1] = models.IntegerField(primary_key=True)
    [column_name_2] = models.CharField(max_length=[length])
    [column_name_3] = models.DateField()
    [column_name_4] = models.ForeignKey(
        "[other_class_name]", models.DO_NOTHING, db_column="[other_column_name]"
    )

    class Meta:
        managed = True
        db_table = "[table_name]"

既にデータベースにテーブルが存在する場合

Django には、既存のデータベースからモデルを自動生成するユーティリティが備わっています。

python manage.py inspectdb > [application_name]/models.py

inspectdb コマンドを実行すると、プロジェクト設定ファイルの DATABASES に設定されているデータベースのテーブルを読み込み、 Django モデルモジュールを標準出力に出力します。

上記の例では、 inspectdb コマンドの出力結果をリダイレクトし、直接 models.py に書き込んでいます。

マイグレーション

アプリケーションのモデルで定義した内容をデータベースに反映するために、マイグレーションを実行します。

Django では、マイグレーションの作成と適用それぞれにコマンドが用意されています。

マイグレーション作成

makemigrations コマンド

python manage.py makemigrations

# アプリケーション単位でマイグレーションファイルを作成
python manage.py makemigrations [application_name]

makemigrations コマンドを実行すると、 プロジェクト設定ファイルの INSTALLED_APPS に設定されているアプリケーションのモデルを読み込み、各アプリケーションディレクトリの migrations ディレクトリ内にマイグレーションファイルが作成されます。

マイグレーション実行

sqlmigrate コマンド

python manage.py sqlmigrate [application_name] [migration_name]

migrate コマンドを実行する前に、 sqlmigrate コマンドで実際にデータベースへ発行される SQL を確認することができます。

migrate コマンド

python manage.py migrate

migrate コマンドを実行すると、 makemigrations コマンドで作成されたマイグレーションの内容がデータベースに反映されます。

開発用サーバ

Django には、開発を迅速に行うために Python だけで書かれた軽量な Web サーバが付属しています。

サーバ起動

runserver コマンド

python manage.py runserver [port]

runserver コマンドを実行すると、 Web サーバが起動します。

引数として、ポート番号を指定することもできます。

ポート番号のデフォルト値は 8000 です。

Web ブラウザで確認

runserver コマンドで起動した Web サーバには、 http://localhost:[port] でアクセスできます。

Django の開発用サーバは、デフォルトではコードを変更して保存する度に自動リロードされる設定になっています。

http://localhost:[port]/[application_name]/ にアクセスし、 Hello Django !! と表示されれば、今回の Django アプリケーションは正常に動作しています。

おわりに

今回は、 Django プロジェクトを新規で立ち上げた際に行うことを中心にまとめました。

実際の開発では、今回取り上げなかったクラスベースの汎用ビューや、フォーム (forms.py) 、管理サイト (Django Admin) など、他にも多くの Django の機能を使用することになると思います。

さらに、 SPA (Single Page Application) との組み合わせに Django REST framework 、ソーシャルログインを実装するために social-auth-app-djangoWSGI サーバを立てるために Gunicorn など、 Django だけでなくサードパーティ製のパッケージも必要になることもあります。

覚えることが多くて大変と思いがちですが、一度覚えてしまえばアプリケーションの実装に集中できるので、やっぱりフレームワークは便利です。

というか、フレームワークを使用せずにすべてを自前で実装する方が絶対大変です…

それでは、皆様も良い Django ライフを!

【GitHub】複数の GitHub アカウントを SSH 接続で使い分ける【Git】

GitHub

はじめに

ちょっと検索するだけで同じような内容の記事が山ほど出てきますが、同一マシン上で複数の GitHub アカウントへの SSH 接続を使い分ける方法についてまとめてみました。

例えば、仕事用の Pro アカウントとプライベート用の Free アカウントや、プロジェクト毎に Pro アカウントを使い分ける場合などを想定しています。

尚、一個人が無料の GitHub アカウントを複数保持することは、規約違反にあたりますのでご注意ください。

help.github.com

前提条件

  • ローカルマシンに Git をインストール済み
  • 複数の GitHub アカウントを保持している
  • Git / GitHub / SSH の基礎知識、使用経験がある

動作環境

OS Version
Windows 10 Pro 1909
Application Version
Git 2.26.0
PowerShell 5.1.18362.752
Hosting Service
GitHub

GitHubSSH 接続する

まずは、各 GitHub アカウントで GitHubSSH 接続できるように設定します。

保持している GitHub アカウント分の SSH キー (公開鍵と秘密鍵) を作成し、それぞれの GitHub アカウントに公開鍵を登録しましょう。

ちなみに、 GitHub ヘルプにも詳しい手順が記載されています。

help.github.com

1. SSH キー (公開鍵と秘密鍵のペア) を作成

1). ssh-keygen コマンド実行

ssh-keygen コマンドで、 SSH キー (公開鍵と秘密鍵のペア) を作成します。

ssh-keygen -t rsa -b 4096 -C "[ID]+[GitHub アカウント名]@users.noreply.github.com -f "id_rsa_github_[GitHub アカウント名]"

GitHub ヘルプでは、 -C オプションに GitHub アカウントのメールアドレスを指定していますが、コメントは生成される公開鍵の中にそのまま埋め込まれることになります。

何の公開鍵か確認するのには役立つかもしれませんが、 GitHub アカウントに登録された公開鍵は誰でも取得可能なため、個人的にはメールアドレスを使用するのに抵抗があります。

コメントを空で登録することもできますが、せっかくなので GitHub で提供されている noreply メールアドレスを登録しました。

noreply メールアドレスについては、以下の記事をご参照ください。

ai-can-fly.hateblo.jp

-f オプションで指定する SSH キー名は任意のもので大丈夫ですが、 GitHub アカウント毎に異なる名前にする必要があるので、どのアカウントの SSH キーか判別できる名前にすることをお勧めします。

ssh-keygen コマンド

ssh-keygen [Options]
Options Default Value Description
-t [type] rsa 作成する鍵の暗号化形式
-b [bits] 2048 (rsa の場合) 作成する鍵のビット数
-C [comment] [user]@[host] コメント
-f [identity] id_rsa (rsa の場合) 鍵ファイル名

2). パスフレーズ登録

次にパスフレーズの入力を求められるので、任意の文字列を入力します。

Enter passphrase (empty for no passphrase): [passphrase]

確認のため、再度入力します。

Enter same passphrase again: [passphrase]

パスフレーズは空で登録することもできますが、セキュリティ向上のため、登録することをお勧めします。

3). SSH キー を .ssh ディレクトリへ移動

ssh-keygen コマンドを実行したカレントディレクトリに SSH キー (公開鍵と秘密鍵) が作成されます。

手順通りに実行していれば、以下の SSH キーが作成されているはずです。

Identity File Key Type
id_rsa_github_[GitHub アカウント名].pub 公開鍵
id_rsa_github_[GitHub アカウント名] 秘密鍵

作成された SSH キーを C:\Users\[user_name]\.ssh ディレクトリに移動します。

.ssh ディレクトリが無ければ、新規作成してください。

2. GitHub アカウントに公開鍵を登録

1). GitHub の設定を開く

GitHub にサインインし、 Settings の「SSH and GPG keys」を開きます。

GitHub - Settings - SSH and GPG keys

開いたら、SSH keys の「New SSH Key」ボタンをクリックします。

2). 公開鍵を登録する

GitHub - Settings - Add new SSH Keys

任意の Title を入力し、先程作成した公開鍵をテキストエディタで開いて中身を全てコピーして、 Key テキストエリアへ貼り付けします。

最後に「Add SSH Key」ボタンをクリックして、公開鍵を登録します。

パスワードを求められたら GitHub アカウントのパスワードを入力しましょう。

これで GitHub アカウントへの公開鍵の登録は完了です。

3. GitHub への SSH 接続テスト

1). ssh コマンド実行

ssh コマンドで GitHubSSH 接続できるかテストを行います。

ssh -Ti C:\Users\[user_name]\.ssh\id_rsa_github_[GitHub アカウント名] git@github.com

今回はSSH キー名を GitHub アカウント毎に変えているので、 -i オプションで使用する秘密鍵を指定する必要があることに注意してください。

ssh コマンド

ssh [Options] [user]@[host]
Options Default Value Description
-T None 仮想端末の割り当てを禁止
-i [identity] $HOME/.ssh/id_rsa (Ver.2 の場合) RSA 認証 / DSA 認証の秘密鍵を指定

2). GitHubSSH キーフィンガープリント確認

初めて GitHub サーバに接続する場合、 SSH キーフィンガープリントが表示されるので、正しい値か確認して問題無ければ yes を入力してください。

The authenticity of host 'github.com (52.192.72.89)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?

GitHubSSH キーフィンガープリントは、 GitHub ヘルプに記載されています。

help.github.com

3). パスフレーズ入力

SSH キー作成時にパスフレーズを登録していた場合、 SSH 接続時にパスフレーズの入力を求められるので、登録していたパスフレーズを入力します。

Enter passphrase for key 'C:\Users\[user_name]\.ssh\id_rsa_github_[GitHub アカウント名]': [passphrase]

認証成功のメッセージが表示されれば、 SSH 接続テストは完了です。

Hi [GitHub アカウント名]! You've successfully authenticated, but GitHub does not provide shell access.

これを保持する GitHub アカウント分、繰り返します。

GitHub アカウント毎に SSH 接続を使い分ける

一言で言ってしまえば「 git clone コマンドの引数を変えて使い分けましょう」って話なのですが、管理しやすいように設定ファイルを作ります。

1. OpenSSH SSH クライアント設定ファイル (ssh_config) 作成

まずは、SSH キーを格納している C:\Users\[user_name]\.sshconfig ファイル (拡張子無しでファイル名が config) を作成します。

テキストエディタconfig ファイルを開き、全ての GitHub アカウントの SSH 接続設定を記述しましょう。

HOST github_[GitHub アカウントA]
    HostName github.com
    User git
    IdentityFile C:\Users\[user_name]\.ssh\id_rsa_github_[GitHub アカウントA]
    Port 22
    identitiesOnly yes

HOST github_[GitHub アカウントB]
    HostName github.com
    User git
    IdentityFile C:\Users\[user_name]\.ssh\id_rsa_github_[GitHub アカウントB]
    Port 22
    identitiesOnly yes

... (全ての GitHub アカウント分を記述)

OpenSSH ssh_config (SSH クライアント設定ファイル)

HOST [host_name]
    HostName [host]
    User [user_name]
    IdentityFile [identity_file]
    Port [port]
    IdentitiesOnly [yes or no]
Options Default Value Description
HostName None ホスト名 (IP アドレスも可)
User None ユーザ名
IdentityFile $HOME/.ssh/id_rsa (Ver.2 の場合) RSA 認証 / DSA 認証の秘密鍵
Port 22 リモートホストのポート番号
IdentitiesOnly no ssh_configファイルで構成された認証 ID ファイルのみを使用

2. git clone での SSH 接続の使い分け

GitHubSSH 接続する際に使い分けを意識するのは、主に git clone をする時だと思います。

接続したい GitHub アカウントの SSH クライアント設定を使用して、 git clone コマンドを実行します。

git clone github_[GitHub アカウント名]:[user_name]/[repository_name].git

カレントディレクトリにリポジトリ名のサブディレクトリが作成され、その中に最新のコミットがチェックアウトされます。

3. Git のリモート設定確認

git clone コマンドを実行したら、クローンされたプロジェクトの内容を確認すると共に、プロジェクトディレクトリ内で git remote -v コマンドを実行して Git のリモート設定を確認します。

$ cd ./[repository_name]
$ git remote -v
origin  github_[GitHub アカウント名]:[user_name/[repository_name].git (fetch)
origin  github_[GitHub アカウント名]:[user_name/[repository_name].git (push)

クローンしたリモートリポジトリの設定が表示されれば、正しく SSH 接続できています。

今後はこのプロジェクト内でリモートリポジトリに対して git fetch / git pull / git push を行うことができます。

おわりに

今回は GitHub アカウント毎に SSH 接続を使い分ける方法について書きましたが、リポジトリ毎にユーザを使い分けるということは、ローカルの Git ユーザもリポジトリ毎に使い分ける必要があります。

正しくユーザ設定を行わないと、誤ったユーザ情報でリポジトリにコミットすることになりかねません。

違うクライアントのユーザで、別のクライアントのリポジトリにコミットするとか、絶対あってはならないことです…

同一マシンでリポジトリ毎にユーザを使い分けるための設定については、別記事で紹介しています。

ai-can-fly.hateblo.jp

これでプライベートマシンを使って、複数のプロジェクトの開発が出来ますね!

お仕事のご依頼、お待ちしています!w

【Oracle Database 12c / 19c】データ移行まとめ【Oracle Data Pump】

ORACLE Database 19c

はじめに

プライベートで使用している Oracle Database のデータ移行を行ったので、ざっくりと手順をまとめました。

Oracle Database 9i までは export / import ユーティリティを使用してデータの入出力を行っていましたが、 10g で Oracle Data Pump が導入され、11g 以降では export / import ユーティリティは非推奨になりました。

ということで、今回は Oracle Data Pump を使用してデータ移行を行います。

TL;DR

  • Oracle Data Pump で入出力する ディレクトリ・オブジェクトを作る
  • ユーザに必要な権限を付与する
  • Oracle Data Pump (expdp / impdp) を使用してダンプファイルを入出力する

動作環境

移行元

OS Version
Windows 10 Pro 1909
Application Version
PowerShell 5.1.18362.752
Database Version
Oracle Database 12c 12.1.0

移行先

OS Version
Windows 10 Pro 1909
Application Version
PowerShell 5.1.18362.752
Database Version
Oracle Database 19c 19.3.0

移行先マシンには、既に Oracle Database 19c がインストールされ、新しいデータベース (CDB と PDB) が作成された状態を前提としています。

Oracle Database 19c のインストールとデータベース作成については、別記事をご参照ください。

ai-can-fly.hateblo.jp

ai-can-fly.hateblo.jp

データ移行

移行概要

移行元データベース (CDB) の PDBスキーマを、移行先データベース (CDB) の PDBOracle Data Pump (expdp / impdp) を使用して移行する。

1. 移行元データベースでの操作

1). ディレクトリ・オブジェクト (DIRECTORY) 作成

SQL*Plus で 移行元データベースの PDB に SYS ユーザで接続し、ディレクトリ・オブジェクト (DIRECTORY) を作成します。

DIRECTORY を作成したら、移行対象のユーザに DIRECTORY への READ / WRITE 権限を付与します。

# SQL*Plus を起動
sqlplus /nolog
-- SYSDBA 権限でログイン
connect sys/[password] as sysdba;

-- PDB へ接続
alter session set container=[pdb_name];

-- DIRECTORY の作成
create or replace directory [directory_name] as [directory_path];

-- ユーザへの権限付与
grant read, write on directory [directory_name] to [user_name];

[directory_path] には、物理ディレクトリをフルパスで指定します。

ディレクトリ・オブジェクト (DIRECTORY) とは

Oracle Database が稼働しているファイルシステム上の物理ディレクトリを表す論理構造で、ディレクトリパスが格納されているオブジェクトです。

DIRECTORY は Oracle Data Pump の入出力先の指定以外に、外部データファイルや外部表データなどの配置場所を指定する際にも使用します。

DIRECTORY の作成には CREATE ANY DIRECTORY システム権限が必要で、DIRECTORY 内のオブジェクトにアクセスするには READ 権限や WRITE 権限が必要です。

2). エクスポート

今回はスキーマ単位で移行を行うため、Oracle Data Pumpのエクスポートをスキーマ・モードで実行します。

docs.oracle.com

SQL*Plus を終了し、PowerShellexpdp コマンドを実行してエクスポートを行います。

# エクスポート
expdp [user_name]/[password]@//[host]:[port]/[pdb_name].[db_domain] directory=[directory_name] dumpfile=[dump_file_name] schemas=[schema_name]

ジョブが正常に完了した旨のログが出力されたら、エクスポートは完了です。

指定したディレクトリ・オブジェクト内に、ダンプファイルが作成されていることを確認してください。

2. 移行先データベースでの操作

1). ユーザ作成

SQL*Plus で移行先データベースへ接続し、データをインポートするユーザを作成します。

# SQL*Plus を起動
sqlplus /nolog
-- SYSDBA 権限でログイン
connect sys/[password] as sysdba;

-- PDB へ接続
alter session set container=[pdb_name];

-- ユーザ作成
create user [user_name] identified by [password];

2). ユーザへの権限付与

DIRECTORY の作成権限、および Oracle Data Pump を使用するための権限をユーザに与えます。

-- ロール
grant "DATAPUMP_EXP_FULL_DATABASE" to [user_name];
grant "DATAPUMP_IMP_FULL_DATABASE" to [user_name];

-- システム権限
grant create any directory to [user_name];
grant create session to [user_name];

-- 表領域割当制限
grant unlimited tablespace to [user_name];

※上記では必要最低限の権限しか与えていないので、実際にデータベースを運用する際には、別途必要な権限を付与してください。

3). ディレクトリ・オブジェクト (DIRECTORY) 作成

ディレクトリ・オブジェクト (DIRECTORY) を作成し、作成したユーザへ READWRITE 権限を付与します。

-- DIRECTORY の作成
create or replace directory [directory_name] as [directory_path];

-- ユーザへの権限付与
grant read, write on directory [directory_name] to [user_name];

[directory_path] には、物理ディレクトリをフルパスで指定します。

4). ダンプファイル格納

移行元データベースのディレクトリ・オブジェクト内にあるダンプファイルを、移行先データベースのディレクトリ・オブジェクトへ移動します。

5). インポート実行

インポートもエクスポートと同じくスキーマ単位で移行を行うため、 Oracle Data Pump のインポートをスキーマ・モードで実行します。

docs.oracle.com

PowerShellimpdp コマンドを実行してインポートを行います。

# インポート
impdp [user_name]/[password]@//[host]:[port]/[pdb_name]/[db_domain] directory=[directory_name] dumpfile=[dump_file_name] schemas=[schema_name]

エクスポートと同様に、ジョブが正常に完了した旨のログが出力されたら、インポートは完了です。

ORA-02291 (整合性制約 (外部キー) 違反) が発生する場合

テーブルに参照整合性 (外部キー) 制約が定義されている場合、インポートされるテーブルの順番の関係でエラーが発生する可能性があります。

その場合は、先にテーブル定義のみをインポートし、対象テーブルの参照整合性 (外部キー) 制約を無効にした上で、次にデータのみインポートを行う必要があります。

# テーブル定義のみインポート
impdp [user_name]/[password]@//[host]:[port]/[pdb_name]/[db_domain] directory=[directory_name] dumpfile=[dump_file_name] schemas=[schema_name] content=metadata_only

# 対象テーブルの参照整合性 (外部キー) 制約を無効にする

# データのみインポート
impdp [user_name]/[password]@//[host]:[port]/[pdb_name]/[db_domain] directory=[directory_name] dumpfile=[dump_file_name] schemas=[schema_name] content=data_only

# 対象テーブルの参照整合性 (外部キー) 制約を有効にする

対象テーブルが多い場合は、全ての参照整合性 (外部キー) 制約を一括で有効化・無効化するプロシージャを作成すると便利です。

おわりに

聡明な Oracle マスターであれば既にお気付きかと思いますが、今回は PDB に存在するスキーマを新 CDB の新 PDB へ移行する方法を紹介しました。

おそらく、こう思われたことでしょう。

「それって、旧 CDB の PDB をアンプラグして、新しい CDB にプラグインすれば済む話じゃ…?」

そうですね、分かってます、僕はその、 Oracle Data Pump を使ってみたくてですね、わざわざこんな回りくどい方法をね、したわけではもちろんないですよ。

Oracle Data Pump でデータ移行してから気付いたんだよ!バーカバーカ!

同じようなデータ移行をするときは、 PDB のアンプラグとプラグインでやりましょうね (๑´ڡ`๑)

【Oracle Database 19c】DBCAを使用したデータベース作成【Database Configuration Assistant】

ORACLE Database 19c

はじめに

Oracle Database 19c のデータベースを作成するにあたり、 Database Configuration Assistant (DBCA) の各ウィザードの設定項目についてまとめました。

今回は僕がプライベートで使用するものなので、ほぼデフォルト値で設定しています。

データベース作成後は変更できない項目もあるので、よく検討して値を決定しましょう。

動作環境

OS Version
Windows 10 Pro 1909
Database Version
Oracle Database 19c 19.3.0
Application
Database Configuration Assistant

Database Configuration Assistant (DBCA) とは

DBCA は Oracle Database に付属するツールで、段階的なガイド付きのワークフローに従ってデータベースの作成・構成の変更・削除を行うことができます。

Oracle 公式ドキュメント - 2日でデータベース管理者

2.3 DBCAを使用したデータベースの作成および管理

DBCA を使用したデータベース作成

Windows の場合、スタートメニューから DBCA を起動できます。

Database configuration Assistant の起動

1. データベース操作の選択

データベース操作の選択

  • データベースの作成
    • データベースを作成する
  • テンプレートの管理
    • データベース・テンプレートの作成、削除を行う

新規でデータベースを作成するので、「データベースの作成」を選択します。

2. データベース作成モードの選択

データベース作成モードの選択

  • 標準構成
    • この画面で入力する項目以外、デフォルト値を使用してデータベースを構成する
  • 拡張構成
    • 次画面からのワークフローに従って各設定値を入力し、データベースを構成する

カスタマイズを行うので「拡張構成」を選択します。

3. データベース・デプロイメント・タイプの選択

データベース・デプロイメント・タイプの選択

  • Oracle 単一インスタンス・データベース
    • 一つのデータベースに対して、一つのデータベース・インスタンスを構成する
  • Oracle Real Application Cluster (RAC) データベース
    • 一つのデータベースに対して、複数のデータベース・インスタンスを構成する
  • Oracle RAC One Node データベース
    • RAC 同様に複数ノードを立ち上げることが可能だが、通常は一つのデータベースに対して一つのデータベース・インスタンスが構成される

RAC 構成にはしないので「Oracle 単一インスタンス・データベース」を選択します。

また、データベース・テンプレートは使用しないので「カスタム・データベース」を選択します。

4. データベースIDの詳細の指定

データベースIDの詳細の指定

  • グローバル・データベース名
    • 初期化パラメータ「DB_NAME」 + 初期化パラメータ「DB_DOMAIN」
  • SID

マルチ・コンテナ・データベースとしてデータベースを作成し、プラガブル・データベースも同時に作成します。

5. データベース記憶域オプションの選択

データベース記憶域オプションの選択

  • データベース・ファイルの記憶域タイプ
  • データベース・ファイルの位置
    • Oracle データベース・ファイルの格納場所を指定する
  • Oracle Managed Files の使用 (OMF)
    • OMF を使用し、ファイルを自動的に作成、命名および管理する

「データベース記憶域属性に次を使用」を選択し、データベース・ファイルの格納場所を指定します。

Oracle Managed Files の使用 (OMF)」にもチェックを入れ、ファイルの管理を自動化しましょう。

6. 高速リカバリ・オプションの選択

高速リカバリ・オプションの選択

「高速リカバリ領域の指定」と「アーカイブ有効化」にチェックを入れます。

7. ネットワーク構成詳細の指定

ネットワーク構成詳細の指定

  • 新規リスナーの作成
    • リスナー名
      • LISTENER
    • リスナー・ポート
      • 1521

リスナーは Net Configuration Assistant (NETCA) でも構成することができますが、特に細かい設定をする必要は無いので、データベース作成と合わせて構成しておきます。

リスナー名とポート番号はデフォルト値を使用すると、lsnrctl コマンドでリスナーを制御する際にリスナー名を省略できます。

8. データベース・オプションの選択

データベース・オプションの選択

データベース・コンポーネントは、使用する予定のあるものにチェックを入れます。

今回は使用する予定は無いので、全てのチェックを外しました。

Windows 版 DBCA の不具合?

データベース・コンポーネント一覧の一番下の項目「Oracle Database Extensions for .NET」が見切れてしまっています…

スクロールバーも表示されていないので、どう頑張っても見ることができません。

チェック有無を切り替えるには、 Tab キーで項目を選択して Space キーで切替を行うしかありません。

9. 構成オプションの指定

1). メモリー

構成オプションの指定 - メモリー

使用するマシンの物理メモリ量に応じて、適切な値を設定します。

以前、物理メモリが 4GB の Windows マシンで自動メモリー管理を 1GB に設定したら、スワップアウトが多発して日常使いはできなくなりました…

自動メモリー管理

自動メモリー管理

自動メモリー管理オプションは、物理メモリが 4GB を超える場合は使用できないようです。

これ、初耳なのですが、そうなんですか…

今どき物理メモリが 4GB 未満でOracle Database を動かすことなんてあるのでしょうか。。
と言いつつ、僕は古いマシン (メモリ 4GB) に Oracle Database を入れてましたけど…

2). サイズ設定

構成オプションの指定 - サイズ設定

ブロック・サイズとユーザ・プロセスの最大同時接続数の設定です。

特に変更せず、デフォルト値を使用します。

と、あっさり決めましたが、ブロック・サイズはデータベース作成後は変更できないので、業務で使用する場合はよく検討してから設定しましょう!

3). キャラクタ・セット

構成オプションの指定 - キャラクタ・セット

Oracle Database 12c Release 1 までは各プラットフォームで使用される標準のキャラクタ・セットが継承されていましたが、 Oracle Database 12c Release 2 以降は Unicode (AL32UTF8) がデフォルトになりました。

ここも特に変更せず、デフォルト値を使用します。

キャラクタ・セットもデータベース作成後は変更できませんが、現在新規でデータベースを作成するなら Unicode (AL32UTF8) に設定しておけば問題無いと思います。

4). 接続モード

構成オプションの指定 - 接続モード

  • 専用サーバ・モード
    • 一つのユーザプロセスに対し、一つのサーバプロセスが立ち上がる
  • 共有サーバー・モード
    • ディスパッチャがユーザプロセスを受け付け、アイドル状態の共有サーバプロセスを割り当てる

ローカルで使用するだけなので「専用サーバ・モード」を選択します。

5). サンプル・スキーマ

構成オプションの指定 - サンプル・スキーマ

サンプル・スキーマは不要なので、チェックを外します。

10. 管理オプションの指定

管理オプションの指定

  • Enterprise Manager (EM) Database Express の構成
    • グローバル・ポートとして EM Database Exporess ポートを構成
      • グローバル・ポートを構成し、CDB の HTTPS ポート経由で CDB の全ての PDB を管理する

Web ブラウザから Oracle Database を管理できるので、 Enterprise Manager (EM) Database Express は有効化しましょう。

今回はマルチ・コンテナ・データベースとしてデータベースを作成するので、 PDB も一緒に管理するためにグローバル・ポートとして構成します。

11. データベース・ユーザー資格証明の指定

データベース・ユーザー資格証明の指定

本来であれば、セキュリティを考慮して各ユーザのパスワードは分けて管理すべきですが、今回はローカルで使用するだけなので、パスワードは共通化しています。

本番環境での運用や、一定のセキュリティを考慮する必要がある場合は、各ユーザ毎にパスワードを設定してください。

12. データベース作成オプションの選択

データベース作成オプションの選択

  • データベースの作成
    • 今まで入力した内容でデータベースを作成する
  • データベース・テンプレートとして保存
    • 今まで入力した内容をデータベース・テンプレートに保存する
  • データベース作成スクリプトの生成
    • 今まで入力した内容でデータベース作成スクリプトを生成する

今後、同じ構成を基にしてデータベースを作成する機会がある場合は、データベース・テンプレートとして保存しておけば、今回の設定内容をデフォルト値として再度データベースを作成できます。

また、データベース作成スクリプトを生成しておけば、 DBCA を使用せずに SQL*Plus からデータベースを作成することも可能です。

13. サマリー

サマリー

各設定項目を確認し、問題無ければ「終了」をクリックします。

データベースの作成まで結構時間が掛かるので、気長に待ちましょう。

ただ、長時間放置した後に確認してみたら、序盤でエラーが出て全てやり直しになることもあるので(僕です…)、15分置きくらいに確認した方がいいと思います。

14. 終了

終了

これでデータベースの作成は完了です。

EM Database Express に接続する URL が表示されるので、控えておきましょう。

と言っても、各 Database 固有のものではなく https://localhost:5500/em でアクセスできます。

おわりに

Oracle Database は高コストだと言われて久しいですが、こういったツールが公式から出ているのは強みの一つなんじゃないかなーと思います。

他のデータベースのことはよく知らないので、実は DBCA よりも使い勝手の良いツールがあったりするかもしれないですけど…

データベースの作成は CREATE DATABASE 文でも行えますが、 Oracle Database では作成時にしか設定できない項目や作成後の変更が容易ではない項目もあるので、初心者は GUI で対話的に設定ができる Database Configuration Assistant を使用することをお勧めします。

これは初心者の僕が言っているので間違いないです!笑

【Gunicorn】インストールから systemd での起動まで【Django】

gunicorn

はじめに

Django アプリケーションを本番環境で運用するにあたり、 WSGI サーバとして Gunicorn を使用する際の設定手順をまとめました。

本番運用には他にも Nginx などの Web サーバが必要ですが、今回は Gunicorn を systemd でサービス化し、 systemctl コマンドで操作するところまでの説明です。

TL;DR

  • 全部 Gunicorn の公式ドキュメントに載ってるよ

docs.gunicorn.org

動作環境

OS Version
CentOS 7.7.1908
Language Version
Python 3.8.1
Application Version
Gunicorn 20.0.4
Django 3.0.3

他の WSGI サーバとの比較

Gunicorn の他に、 Python Web アプリケーションで人気のある WSGI サーバとして、 uWSGI や Waitress などがあります。

今回初めて WSGI サーバを構築するので正しい評価ではないと思いますが、色々調べた結果、以下の理由で Gunicorn を選択しました。

  • 他の WSGI サーバと比べて、シンプルな実装でサーバリソースが軽量である
  • uWSGI の方が大幅にカスタマイズ可能で高機能だが、 Gunicorn も機能としては必要十分である
  • 初めて WSGI サーバを構築するなら、手軽で利用事例も多い Gunicorn の方がおすすめ

Gunicorn のインストールと起動

インストール

1. PyPI からインストール

まずは、 Python の仮想環境下で pip で Gunicorn をインストールします。

今回は既に Django アプリケーションが作成済みの状態を想定しているので、カレントディレクトリは Django プロジェクトルートになります。

# 仮想環境をアクティベート
. venv/bin/activate

# Gunicorn をインストール
pip install gunicorn

2. Gunicorn で Django をテスト起動

Gunicorn をインストールしたら gunicorn コマンドで Django アプリケーションをテスト起動します。

gunicorn [Django Project Name].wsgi:application

Web ブラウザを起動して http://localhost:8000 を開き、 Django アプリケーションが表示されればインストールは成功です。

コマンド

Gunicorn は gunicorn コマンドで起動します。

gunicorn コマンド

gunicorn [Options] $(MODULE_NAME):$(VARIABLE_NAME)
Target Explanation
MODULE_NAME WSGI モジュール名(カレントディレクトリからのドット付きフルパスで、拡張子は不要)
VARIABLE_NAME WSGI モジュール内の WSGI オブジェクト名

今回使用する主なオプションを以下にまとめました。

Options Default Value Explanation
-b $(HOST):$(PORT), --bind $(HOST):$(PORT) 127.0.0.1:8000 バインドするサーバソケットを指定
-c $(PATH), --config $(PATH) None 設定ファイルのパスを指定
-e $(KEY)=$(VALUE), --env $(KEY)=$(VALUE) [] 環境変数の設定
-d, --daemon False Gunicorn プロセスをデーモン化

設定ファイル

Gunicorn の設定ファイルは、拡張子付きの Python ソースファイルになります。

例えば、 gunicorn.conf.py などです。

CLI で実行する gunicorn コマンドのオプションと同様に、設定したいオプションと値を記述します。

import multiprocessing

bind = "127.0.0.1:8000"
daemon = True
workers = multiprocessing.cpu_count() * 2 + 1

設定の優先順位

同じオプションに対して複数の設定が存在した場合、適用される値は優先度の高い順に

  1. CLI で指定した値
  2. 設定ファイルの値
  3. フレームワーク固有の値

となります。

Django アプリケーションの起動

通常起動

起動

gunicorn [Django Project Name].wsgi:application

通常起動では Gunicorn 起動中はコンソールが専有され、常にログが表示されます。

開発時やテストを行う際に使用することが多いと思います。

停止

Ctrl + C

デーモン起動(バックグラウンド実行)

起動

gunicorn --daemon [Django Project Name].wsgi:application

本番運用時に手動で gunicorn コマンドを実行する場合は、デーモンモードで起動することが主だと思います。

停止

プロセスを調べて kill コマンドで停止します。

いちいちプロセスを調べて停止するのは面倒ですが、後述する systemd でサービス化を行えば systemctl コマンドで起動・停止ができるようになります。

systemd による起動と停止

1. Unit 作成

systemd で Gunicorn を起動するための Unit を作成します。

servicesocket の拡張子以外のファイル名は揃える必要があるので注意してください。

正直 Linux はあまり自信が無いので、 Gunicorn の 公式ドキュメント を参考にしましょう…

docs.gunicorn.org

Service

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
Type=notify
# the specific user that our service will run as
User=[User Name]
Group=[Group Name]
RuntimeDirectory=gunicorn
WorkingDirectory=[/ から Django Project Root までパス]/[Django Project Root]
ExecStart=[/ から gunicorn コマンドまでのパス]/gunicorn --config gunicon.conf.py [Django Project Name].wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

ベースは Gunicorn の 公式ドキュメント にあったものを使用しています。

WorkingDirectoryExecStart を対象の Django アプリケーションのパスに変更しましょう。

Socket

/etc/systemd/system/gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
# User=www-data
# Optionally restrict the socket permissions even more.
# Mode=600

[Install]
WantedBy=sockets.target

こちらもベースは Gunicorn の 公式ドキュメント にあったものです。

特に変更点はありませんが、強いて言うなら User くらいでしょうか。

2. Socket の起動

Unit を作成したら、 systemctl コマンドで起動します。

systemctl コマンドを使用する際は、ユーザの権限に応じて sudo コマンドも併用してください。

systemctl enable --now gunicorn.socket

これで gunicorn.socket で指定した /run/gunicorn.sockトラフィックが流れると、自動的に gunicorn.service が起動されるようになります。

Gunicorn を systemd の Socket から起動する場合、監視している UNIX ドメインソケット(今回の例だと /run/gunicorn.sock )へトラフィック流すように、 Web サーバ側で設定をする必要があります。

systemctl コマンド

起動 / 停止 / 再起動

# 起動
systemctl start gunicorn.socket

# 停止
systemctl stop gunicorn.socket

# 再起動
systemctl restart gunicorn.socket

自動起動

# 有効化
systemctl enable gunicorn.socket
# 自動起動有効化と同時に起動
systemctl enable --now gunicorn.socket

# 無効化
systemctl disable gunicorn.socket

状態確認

# gunicorn.socket の状態確認
systemctl status gunicorn.socket

# gunicorn.service の状態確認
systemctl status gunicorn

3. 動作確認

curl コマンドで、設定した UNIX ドメインソケットへリクエストを送信して動作を確認します。

curl --unix-socket /run/gunicorn.sock localhost

コンソール上に Django アプリケーションの HTML が表示されれば、 Gunicorn は正常に動作しています。

また、 systemctl status gunicorngunicorn.service の状態も確認しておきましょう。

おわりに

今回取り上げた Socket から Service を起動する方法の他に、 Service 単体で Gunicorn を常時起動しておき、 Web サーバから Gunicorn がバインドされているURI ( e.g. 127.0.0.1:8000 ) へ転送する方法もあるようです。

ただ、Socket の使用有無について色々調べましたが、いまいちそれぞれのメリット・デメリットが分かりませんでした…

Gunicornの 公式ドキュメント には Socket からの起動方法が書かれていたので、今回は Socket 有の方法を紹介してみました。

どなたか詳しい方、systemd について分かりやすく教えてください!