Record / Server Side
RDSインスタンスの作成からDjangoでDB接続
DB Django
1. RDS MySQLインスタンスの作成
AWSコンソールでRDSサービスに移動し、MySQLデータベースを作成します。
料金最安を目指す
- 「データベースの作成」をクリック
- エンジンタイプ: MySQL を選択
- テンプレート: サンドボックス
- 可用性と耐久性: シングルAZ DBインスタンスデプロイ(1インスタンス)
- DBインスタンス識別子、マスターユーザー名、パスワードを設定
- インスタンスの設定: db.t4g.micro (1GiB RAM…)
- ストレージ: ストレージ割当: 20GB
同ページ下部の「接続」セクションでEC2を指定
接続: EC2コンピューティングリソースに接続
- EC2インスタンス: (EC2インスタンスを選択)
2 RDS MySQL データベースの初期設定
ツールをインストール
MySQLクライアントをインストール
sudo dnf install mariadb105 mariadb105-develインストール後、接続テストを実行:
mysql --version
# RDSエンドポイントへの接続テスト
mysql -h your-rds-endpoint.region.rds.amazonaws.com -u your_master_username -pMariaDBについて
Amazon Linux 2023では、MySQL互換のMariaDBクライアントがデフォルトで提供されています。
- MariaDBとは: MySQLから派生したオープンソースのデータベース管理システムで、MySQL互換性を保持
- なぜMariaDB: Amazon Linuxのパッケージリポジトリでは、MySQLクライアントの代わりにMariaDBクライアントが標準提供されている
- 互換性: MariaDBクライアントはMySQLサーバー(RDS MySQLを含む)に問題なく接続可能
- 機能: MySQLクライアントと同じコマンドや機能を使用できる
つまり、mariadb105をインストールしても、RDS MySQLへの接続や操作には全く問題ありません。実際、多くのLinuxディストリビューションで、MySQLクライアントの代替としてMariaDBクライアントが採用されています。
Python MySQLライブラリのインストール
# 仮想環境をON
cd /var/www/django-5
source venv/bin/activate
pip install mysqlclient
# または
pip install pymysql
# 仮想環境をOFF
deactivateRDS MySQL データベース作成
RDSインスタンスを作成した後、実際に使用するデータベースを作成する必要があります。以下の手順で進めます。
1. RDSエンドポイントの確認
2. MySQLクライアントでRDSに接続
# マスターユーザーで接続
mysql -h your-rds-endpoint.region.rds.amazonaws.com -u your_master_username -p
# パスワードを入力3. データベースの作成
# データベース名
myfirst_database_2512-- 接続後、MySQLプロンプトで以下を実行
CREATE DATABASE myfirst_database_2512 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- データベースが作成されたか確認
SHOW DATABASES;
-- データベースを選択
USE myfirst_database_2512;
-- 接続を終了
EXIT;3 環境変数の設定とDjango settings.py の設定
セキュリティ向上のため、機密情報を環境変数で管理します。
.env 環境の準備
.envファイルの配置場所
.envファイルは、Djangoプロジェクトのルートディレクトリ(manage.pyがあるディレクトリ)に配置します。
# ディレクトリ構造の例
/var/www/django-5/
├── manage.py
├── .env # ← ここに配置
├── myproject/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── myapp/
└── venv/仮想環境はONのままで作業
- .envファイルの作成: 仮想環境の状態は関係なし(テキストファイルを作成するだけ)
- python-dotenvのインストール: 仮想環境をONにして実行
- Djangoの実行: 仮想環境をONにして実行
python-dotenvのインストール
.envファイルを読み込むために、python-dotenvをインストールします。
# 仮想環境がONの状態で実行
cd /var/www/django-5
source venv/bin/activate
pip install python-dotenv接続
.envファイルの作成
# 1. プロジェクトルートに移動
cd /var/www/django-5
# 2. .envファイルを作成
vi .env
# 3. 以下の内容を記述
DB_NAME=your_database_name # 前項2で作成したデータベース名
DB_USER=your_master_username # RDS作成時のマスターユーザー名
DB_PASSWORD=your_password # RDS作成時のマスターパスワード
DB_HOST=your-rds-endpoint.region.rds.amazonaws.com
DB_PORT=3306
# 4. 保存して閉じる(viの場合: ESCキー → :wq → Enter).envファイルのセキュリティ上の注意
- .gitignoreに追加:
.envファイルをGitにコミットしないよう設定
# .gitignore に以下を追加
.env
*.env- 権限設定: .envファイルの権限を適切に設定
chmod 600 .envsettings.pyでの.env読み込み設定
# settings.py の先頭に追加
import os
from pathlib import Path
from dotenv import load_dotenv
# .envファイルを読み込む
load_dotenv()
# 既存のBASE_DIR設定の下に以下を追加
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('DB_NAME'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': os.environ.get('DB_HOST'),
'PORT': os.environ.get('DB_PORT', '3306'),
'OPTIONS': { # MySQL Strict Mode ON
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}
}
}MySQL Strict Mode を有効にします
- 開発段階: 開発初期であれば、この警告は無視しても動作に問題はありませんが、本番環境では必ず設定することを推奨します
- データ整合性: 厳格モードにより、データの切り詰めや型の不一致などのエラーが早期に検出されます
動作確認
# 仮想環境ONの状態で
python manage.py check
# モデルを変更したとき
python manage.py makemigrations
# データベース接続テスト
python manage.py migrate成功時の出力例
1. python manage.py check の成功例
(venv) [ec2-user@ip-172-31-35-28 django-5]$ python manage.py check
System check identified no issues (0 silenced).この出力が表示されれば、Django設定に問題がないことを示します。
2. python manage.py migrate の成功例
(venv) [ec2-user@ip-172-31-35-28 django-5]$ python 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 auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK各マイグレーションが「OK」と表示されれば、データベース接続とテーブル作成が正常に完了しています。
失敗時の出力例
接続エラーの場合
django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on 'your-rds-endpoint' (110)")
# または
django.db.utils.OperationalError: (1045, "Access denied for user 'username'@'ip-address' (using password: YES)")よくある失敗の原因:
- セキュリティグループ: RDSのセキュリティグループでEC2のIPアドレスまたはセキュリティグループが許可されていない
- 認証情報: .envファイルのDB_USER、DB_PASSWORD、DB_NAMEが間違っている
- エンドポイント: DB_HOSTのエンドポイントが間違っている
- データベース未作成: CREATE DATABASE コマンドを実行していない
4 Djangoでサンプルテーブルを作成して表示する
MySQL
MySQL CLIでサンプルテーブルを作成する方法
DjangoのモデルではなくMySQL CLIで直接テーブルを作成する場合の手順です。
1. MySQL CLIへの接続、データベースの選択
# EC2インスタンスからRDSに接続
mysql -h your-rds-endpoint.region.rds.amazonaws.com -u your_master_username -p
# パスワードを入力
# 使用するデータベースを選択
USE your_database_name;
# 現在のデータベースを確認
SELECT DATABASE();2. サンプルテーブルの作成
商品テーブルの例:
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(200) NOT NULL COMMENT '商品名',
price INT NOT NULL COMMENT '価格',
description TEXT COMMENT '説明',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '作成日時',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日時'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;4. サンプルデータの挿入
INSERT INTO products (name, price, description) VALUES
('ノートパソコン', 98000, '高性能な15インチノートパソコン'),
('マウス', 2500, 'ワイヤレスマウス'),
('キーボード', 5800, 'メカニカルキーボード'),
('モニター', 35000, '27インチ4Kモニター'),
('USBメモリ', 1200, '32GB USBメモリ');5. データの確認
-- 全データを表示
SELECT * FROM products;
-- 件数を確認
SELECT COUNT(*) FROM products;
-- 特定の条件で検索
SELECT * FROM products WHERE price > 3000;6. テーブル構造の確認
-- テーブル構造を表示
DESCRIBE products;
-- または
SHOW CREATE TABLE products;MySQL CLIの終了
-- MySQLから切断
EXIT;
-- または
quit;注意事項
- 文字コード:
utf8mb4を使用することで日本語や絵文字に対応 - 照合順序:
utf8mb4_unicode_ciで大文字小文字を区別しない比較が可能 - ENGINE: InnoDBはトランザクションをサポートし、本番環境に適している
既存のテーブルからDjangoモデルを自動生成
MySQL CLIで直接作成したテーブルをDjangoで使用する場合:
# 既存のテーブルからモデルを自動生成
# 【注意】上書きされる
python manage.py inspectdb products > myapp/models.py
# 既存のmodels.pyを上書きせず、別ファイルに出力
python manage.py inspectdb products > myapp/models_generated.pyDjango
1. モデルの作成
まず、アプリ内のmodels.pyでモデル(テーブル定義)を作成します。
# myapp/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200, verbose_name='商品名')
price = models.IntegerField(verbose_name='価格')
description = models.TextField(verbose_name='説明', blank=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='作成日時')
updated_at = models.DateTimeField(blank=True, null=True, db_comment='更新日時')
class Meta:
verbose_name = '商品'
verbose_name_plural = '商品'
def __str__(self):
return self.name2. マイグレーションの実行
モデルを作成したら、データベースにテーブルを作成します。
# 仮想環境ONの状態で
python manage.py makemigrations
python manage.py migrateマイグレーションコマンドの動作
はい、その理解で正しいです。models.pyにモデルを定義して、これらのコマンドを実行することでテーブルが作成されます。
コマンドの役割
- python manage.py makemigrations
models.pyの変更を検出- 変更内容をマイグレーションファイルとして記録(例:
0001_initial.py) - このファイルは
myapp/migrations/ディレクトリに保存される - まだデータベースには何も変更されていない
- python manage.py migrate
- マイグレーションファイルを読み込む
- 実際にデータベースにテーブルを作成(CREATE TABLE文を実行)
- RDSのMySQLに接続して、
models.pyで定義したテーブル構造を作成
実行例
# makemigrationsの実行
$ python manage.py makemigrations
Migrations for 'myapp':
myapp/migrations/0001_initial.py
- Create model Product
# migrateの実行
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, myapp, sessions
Running migrations:
Applying myapp.0001_initial... OK重要なポイント
- models.pyの変更が起点:
models.pyでクラスを定義すると、Djangoがそれをデータベーステーブルとして認識 - 2段階プロセス: makemigrations(変更の記録) → migrate(実行)
- 自動的にテーブル作成: SQLのCREATE TABLE文を書く必要がない
- 変更履歴の管理: マイグレーションファイルで変更履歴が追跡可能
確認方法
テーブルが作成されたか確認するには、MySQL CLIで:
-- RDSに接続
mysql -h your-rds-endpoint -u your_username -p
-- データベースを選択
USE your_database_name;
-- テーブル一覧を表示
SHOW TABLES;
-- テーブル構造を確認
DESCRIBE myapp_product;これでmyapp_productテーブル(アプリ名_モデル名の形式)が作成されていることが確認できます。
既にテーブルがある場合
既存テーブルとDjangoモデルの不一致について
MySQL CLIで既にテーブルを作成している場合、Djangoのマイグレーションで同じ名前のテーブルは作成されません。しかし、カラムの不一致がある場合は注意が必要です。
状況の整理
- MySQL CLIで作成:
id、updated_atなどのカラムを含むテーブル - Django models.py: これらのカラムを定義していない
どうなるか
- マイグレーション実行時
- Djangoは既存のテーブルを検出すると、通常はスキップします
- ただし、
--fakeオプションを使わない限り、エラーが発生する可能性があります
- Django ORM使用時
- Djangoは
models.pyに定義されていないカラムを無視します updated_atは更新されません(Djangoが認識していないため)- データ取得時、存在しないはずのカラムがあっても問題なく動作します
推奨される対処法
方法1: Djangoモデルを既存テーブルに合わせる
# myapp/models.py
from django.db import models
class Product(models.Model):
id = models.AutoField(primary_key=True) # 明示的に定義
name = models.CharField(max_length=200, verbose_name='商品名')
price = models.IntegerField(verbose_name='価格')
description = models.TextField(verbose_name='説明', blank=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='作成日時')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新日時') # 追加
class Meta:
db_table = 'products' # 既存のテーブル名を指定
managed = False # Djangoにテーブルを管理させない場合
def __str__(self):
return self.name方法2: inspectdbで既存テーブルからモデルを生成
# 既存テーブルからDjangoモデルを自動生成
python manage.py inspectdb products > myapp/models_from_db.py
# 生成されたモデルを確認して、models.pyにコピー方法3: マイグレーションをフェイクする
# 既存テーブルに対してマイグレーションを「適用済み」として記録
python manage.py migrate --fake-initial注意点
- managed = False: このオプションを使うと、DjangoはCREATE/DROP TABLEを実行しません
- auto_now と auto_now_add: これらはDjangoレベルでのみ機能し、MySQL CLIからの直接更新では動作しません
- カラムの不一致: models.pyに定義していないカラムは、ORMでは使用できません
ベストプラクティス
開発初期段階では、Djangoのマイグレーション機能だけを使うことをおすすめします。MySQL CLIで直接テーブルを作成すると、Djangoとの整合性が取りづらくなります。
既にCLIでテーブルを作成してしまった場合は、inspectdbコマンドでモデルを生成し、それを基に調整するのが最も確実です。
inspectdbの結果にidが表示されない
from django.db import models
class Products(models.Model):
name = models.CharField(max_length=200, db_comment='商品名')
price = models.IntegerField(db_comment='価格')
description = models.TextField(blank=True, null=True, db_comment='説明')
created_at = models.DateTimeField(blank=True, null=True, db_comment='作成日時')
updated_at = models.DateTimeField(blank=True, null=True, db_comment='更新日時')
class Meta:
managed = False
db_table = 'products'inspectdbの結果にidが表示されない理由
inspectdbコマンドの結果にidフィールドが表示されていないのは正常な動作です。これはDjangoの仕様によるものです。
理由
- Djangoの自動生成: Djangoは明示的に主キーを定義しない場合、自動的に
id = models.AutoField(primary_key=True)を追加します - inspectdbの動作:
inspectdbは既存テーブルに主キーが存在する場合、それが自動生成されたものとみなし、モデル定義には含めません - 冗長性の回避: デフォルトの
idフィールドをわざわざ明示する必要がないため、省略されます
実際のテーブル構造を確認
MySQL CLIでテーブル構造を確認してみましょう:
DESCRIBE products;おそらく以下のような構造になっているはずです:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(200) | NO | | NULL | |
| price | int | NO | | NULL | |
| description | text | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+使用方法
このまま使用できます:
# myapp/models.py
from django.db import models
class Products(models.Model):
name = models.CharField(max_length=200, db_comment='商品名')
price = models.IntegerField(db_comment='価格')
description = models.TextField(blank=True, null=True, db_comment='説明')
created_at = models.DateTimeField(blank=True, null=True, db_comment='作成日時')
updated_at = models.DateTimeField(blank=True, null=True, db_comment='更新日時')
class Meta:
managed = False
db_table = 'products'
def __str__(self):
return self.nameidフィールドは自動的に利用可能:
# ビューなどで使用する場合
product = Products.objects.get(id=1) # idは自動的に存在する
print(product.id) # 問題なく動作明示的にidを定義したい場合
もし明示的にidフィールドを定義したい場合は、以下のように追加できます:
class Products(models.Model):
id = models.AutoField(primary_key=True) # 明示的に定義
name = models.CharField(max_length=200, db_comment='商品名')
price = models.IntegerField(db_comment='価格')
description = models.TextField(blank=True, null=True, db_comment='説明')
created_at = models.DateTimeField(blank=True, null=True, db_comment='作成日時')
updated_at = models.DateTimeField(blank=True, null=True, db_comment='更新日時')
class Meta:
managed = False
db_table = 'products'まとめ
inspectdbの結果にidがないのは正常- Djangoが自動的に
idフィールドを提供するため、明示的な定義は不要 - そのまま使用しても
product.idでアクセス可能 - 必要であれば明示的に
id = models.AutoField(primary_key=True)を追加できる
Django つづき (Admin)
3. Django Adminでの管理
Django Adminは管理画面用のツールです。モデルをAdminに登録すると、ブラウザからデータの追加・編集・削除ができます。
admin.pyでモデルを登録:
# myapp/admin.py
from django.contrib import admin
from .models import Product
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ('name', 'price', 'created_at') # 一覧に表示する項目
search_fields = ('name',) # 検索可能な項目
list_filter = ('created_at',) # フィルタ項目4. 管理ユーザーの作成
Admin画面にアクセスするためのスーパーユーザーを作成します。
python manage.py createsuperuser
# ユーザー名、メールアドレス、パスワードを入力スーパーユーザー情報の保存場所
python manage.py createsuperuserで作成したユーザー情報は、Djangoのデフォルトの認証システムによって管理され、データベースに保存されます。
保存先テーブル (MySQL)
- auth_user: ユーザーの基本情報(ユーザー名、メールアドレス、パスワードハッシュなど)が保存されるメインテーブル
Django shellで確認:
python manage.py shell
# Pythonシェル内で
from django.contrib.auth.models import User
# 全ユーザーを表示
users = User.objects.all()
for user in users:
print(f"ID: {user.id}, Username: {user.username}, Superuser: {user.is_superuser}")
# スーパーユーザーのみ表示
superusers = User.objects.filter(is_superuser=True)
for user in superusers:
print(f"{user.username} - {user.email}")関連する他のテーブル
Djangoの認証システムは、複数のテーブルで構成されています:
- auth_user: ユーザー基本情報
- auth_group: ユーザーグループ情報
- auth_user_groups: ユーザーとグループの関連付け
- auth_permission: パーミッション情報
- auth_user_user_permissions: ユーザーごとの個別パーミッション
セキュリティに関する注意
- パスワードは暗号化:
password列にはハッシュ化されたパスワードが保存され、平文では保存されません - ハッシュアルゴリズム: Djangoはデフォルトで
PBKDF2アルゴリズムを使用してパスワードをハッシュ化します - 直接編集は非推奨: データベースから直接パスワードを変更することは避け、Djangoの管理コマンドを使用してください
パスワードの変更方法
# 管理コマンドでパスワードを変更
python manage.py changepassword username
# または Django shell で
python manage.py shell
from django.contrib.auth.models import User
user = User.objects.get(username='username')
user.set_password('new_password')
user.save()まとめ
- スーパーユーザー情報はRDSのauth_userテーブルに保存される
- パスワードはハッシュ化されて安全に保存される
- MySQL CLIまたはDjango shellで確認可能
- パスワード変更は必ずDjangoのコマンドを使用する
5. Admin画面でデータ追加
- 開発サーバーを起動:
python manage.py runserver 0.0.0.0:8000 - ブラウザで
http://your-ec2-ip:8000/admin/にアクセス - 作成したスーパーユーザーでログイン
- 「商品」からサンプルデータを追加
6. ビューとテンプレートで一覧表示
views.pyでビューを作成:
# myapp/views.py
from django.shortcuts import render
from .models import Product
def product_list(view):
products = Product.objects.all() # 全商品を取得
return render(request, 'myapp/product_list.html', {'products': products})urls.pyでURLを設定:
# myproject/urls.py
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('products/', views.product_list, name='product_list'),
]テンプレートを作成:
<!-- myapp/templates/myapp/product_list.html -->
<!DOCTYPE html>
<html>
<head>
<title>商品一覧</title>
</head>
<body>
<h1>商品一覧</h1>
<table border="1">
<tr>
<th>商品名</th>
<th>価格</th>
<th>説明</th>
</tr>
{% for product in products %}
<tr>
<td>{{ product.name }}</td>
<td>{{ product.price }}円</td>
<td>{{ product.description }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>7. 動作確認
http://your-ec2-ip:8000/products/にアクセスして一覧が表示されることを確認
トラブルシューティング: 商品が0個と表示される
問題の状況
MySQLでは5件のデータが確認できるのに、Djangoのビューで「商品が0個」と表示される場合があります。
原因の特定
この問題は、Djangoのモデルが参照しているテーブルと、実際のデータが入っているテーブルが異なることが原因です。
上記の例では:
productsテーブル: 実際のデータが入っている(5件)myapp_productテーブル: Djangoのモデルが参照しているテーブル(おそらく空)
解決方法
方法1: モデルのdb_tableを正しく設定する
models.pyで、正しいテーブル名を指定します:
class Product(models.Model):
name = models.CharField(max_length=200, db_comment='商品名')
price = models.IntegerField(db_comment='価格')
description = models.TextField(blank=True, null=True, db_comment='説明')
created_at = models.DateTimeField(blank=True, null=True, db_comment='作成日時')
updated_at = models.DateTimeField(blank=True, null=True, db_comment='更新日時')
class Meta:
managed = False
db_table = 'products' # ここで正しいテーブル名を指定方法2: Django shellで確認する
どのテーブルを参照しているか確認します:
python manage.py shellfrom myapp.models import Product
# モデルが参照しているテーブル名を確認
print(Product._meta.db_table) # 'myapp_product' または 'products' が表示される
# データを取得してみる
products = Product.objects.all()
print(products.count()) # 件数を確認
print(products) # データの内容を確認方法3: 生のSQLで確認する
Django shellから直接SQLを実行して確認:
from django.db import connection
with connection.cursor() as cursor:
# myapp_product テーブルの内容を確認
cursor.execute("SELECT * FROM myapp_product")
rows = cursor.fetchall()
print(f"myapp_product: {len(rows)}件")
# products テーブルの内容を確認
cursor.execute("SELECT * FROM products")
rows = cursor.fetchall()
print(f"products: {len(rows)}件")修正後の確認手順
models.pyを修正して保存- Djangoサーバーを再起動:
python manage.py runserver 0.0.0.0:8000 - ブラウザで
http://your-ec2-ip:8000/products/にアクセス - 5件のデータが表示されることを確認
まとめ
- Djangoは
Meta.db_tableで指定されたテーブルを参照する - 指定がない場合、
アプリ名_モデル名(小文字)のテーブルを自動生成・参照する - 既存のテーブルを使う場合は、必ず
db_tableを正しく設定する managed = FalseでDjangoによるテーブル管理を無効化する