Djangoで複数のDBを使用する方法について検証する(usingを使う場合)
Djangoで複数のDBを使用して、向き先を切り替える方法について検証した。
公式ドキュメントは以下
docs.djangoproject.com
理由
本番で稼働させるWEBアプリケーションでは、負荷分散のためにread-onlyのRDBと書き込み用のRDBの複数台構成にして、複数のDB間で向き先を切り替えるという場面が結構あると思われるので、Djangoで実現する方法について調べておく。
Docker Compose
検証用のMySQLにはDockerコンテナを使用する。
[docker-compose.yml]
version: "3" services: db_server1: image: mysql:5.7 ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: sample db_server2: image: mysql:5.7 ports: - "3307:3306" environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: sample
settings.py
settings.pyには以下のように設定を2つ書く。
デフォルトでは「default」に設定したDBが使用される。
[settings.py]
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "sample", "USER": "root", "PASSWORD": "password", "HOST": "127.0.0.1", "PORT": "3306", }, "dbserver2": { "ENGINE": "django.db.backends.mysql", "NAME": "sample", "USER": "root", "PASSWORD": "password", "HOST": "127.0.0.1", "PORT": "3307", }, }
マイグレーション
まずはDockerコンテナを起動する。
$ docker-compose up -d
次に、マイグレーションを実行する。
何もオプションを付けずにマイグレーションを実行すると、「default」のDBのみにマイグレーションが適用される。
「default」以外のDBにマイグレーションを適用する場合は、オプションで対象のDBを指定する必要がある。
$ python manage.py migrate #「default」に対してマイグレーションを適用 $ python manage.py migrate --database=dbserver2 #「dbserver2」に対してマイグレーションを適用
views.py
views.pyに以下のように検証用のコードを書く。
[views.py]
from django.contrib.auth.models import User from django.http import HttpResponse def index(request): user1 = User(username="fizz") user1.set_password("password") user1.save() user2 = User(username="buzz") user2.set_password("password") user2.save(using="dbserver2") return HttpResponse("Hello, world. You're at the polls index.")
「default」ではないDBにデータをinsertする場合は、saveの引数に「using=${DB名}」を指定する。
user2.save(using="dbserver2")
検証
サーバーを起動してhttp://127.0.0.1:8000/polls/にアクセスする。
その後、データを確認する。
・MySQL1号機
mysql> select id, username from auth_user; +----+----------+ | id | username | +----+----------+ | 1 | fizz | +----+----------+ 1 row in set (0.00 sec) mysql>
・MySQL2号機
mysql> select id, username from auth_user; +----+----------+ | id | username | +----+----------+ | 1 | buzz | +----+----------+ 1 row in set (0.00 sec) mysql>
以上で検証完了。
検証用のコードは以下
https://github.com/kamatimaru/multiple_databases_practice
公式ドキュメントによると、ルーターという機能を使うやり方もあるそうなので、別の機会に検証する。
docs.djangoproject.com