はじめに
みなさん、こんにちは。ゆうたです。
今回はタイトルにも記載した、djangoでDBテーブルが作成できない事象に遭遇したので記事にしたいと思います。
※初学者なので認識相違があればご指摘頂けますと幸いです。
環境
Python 3.12.0
Django 5.0.6
結論
DBに直接ログインしてテーブルを作成
やろうとしたこと
CartテーブルとCartItemテーブルを作成したい。
事象について
DBマイグレーションを実行して管理画面にテーブルは表示されるものの、管理画面からレコードをINSERTしようとするとERROR: relation "テーブル名" does not exist
というメッセージでエラーが出力される。
管理画面の赤枠のテーブル名を押下すると以下のエラー画面になる。
各種ファイル
from django.db import models
# Create your models here.
class BaseMeta(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class CartModel(BaseMeta):
cart_id = models.BigAutoField(primary_key=True)
class CartItemModel(BaseMeta):
name = models.ForeignKey(ProductModel, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
cart_id = models.ForeignKey(CartModel, on_delete=models.CASCADE)
version: "3.9"
services:
db:
image: postgres
platform: linux/amd64
volumes:
- db-data:/var/lib/postgresql/data
ports:
- "5433:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_DB=django_develop #データベース名
- POSTGRES_PASSWORD=XXXX
healthcheck:
test: "psql -U postgres"
interval: 5s
timeout: 5s
retries: 5
web:
build: .
command: python manage.py runserver 0.0.0.0:3000
volumes:
- .:/code
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
volumes:
db-data:
調べてわかったこと
以下のサイトから今回のエラーはマイグレーションがDBに適用されない場合に発生するとのことでした。
参考サイト
DBに直接ログインしてテーブルの状態を確認する必要がありそうです。
参考サイト
こちらのサイトでも以下のように記載がありました。
エラー回避のためどうしても直接データベースを変更するケースが出てくる。
ということでコンテナからDBにログインしてテーブルの状態を見ていきます。
※コンテナからDBに接続する流れは、以下のサイトを参考にしました。
【Python/Django】よく使うコマンドのまとめ(3)
PostgreSQLの使い方
DBコンテナを起動しコンテナにログイン
コマンド:docker-compose exec <コンテナ名> bash
コンテナにログイン後、postgresqlに接続
コマンド:psql -U postgres
データベースの一覧を確認する
※\はMacのキーボードから option + ¥ で入力可
コマンド:\l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
----------------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
django_develop | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
指定したデータベースへ接続する
コマンド:\c django_develop
テーブル一覧を表示
コマンド:\d
Schema | Name | Type | Owner
--------+-----------------------------------+----------+----------
public | Ec_OrderdModel | table | postgres
public | Ec_OrderdModel_id_seq | sequence | postgres
public | Ec_ProductModel | table | postgres
public | Ec_ProductModel_id_seq | sequence | postgres
ここまでの調査でマイグレーションしたにも関わらず、CartテーブルとCartItemテーブルが存在しないことが判明しました。
解消したやり方
DBコンテナにログインし、PostgreSQLに接続してCREATE TABLEで直接テーブルを作成
色々調べながらコンテナの中で直接テーブルを作成しようとするも中々うまくいかない。。
※特にデータ型の指定をどういう風に指定すればいいかわからない。
失敗例
django_develop=# CREATE TABLE "CartModel" (
django_develop(# "cart_id" BigAutoField NOT NULL PRIMARY KEY
django_develop(# );
ERROR: type "bigautofield" does not exist
LINE 2: "cart_id" BigAutoField NOT NULL PRIMARY KEY
^
django_develop=#
調べていくうちにsqlmigrate
というコマンドを使えば、マイグレーションする時に実行するコマンドを確認できると公式ドキュメントに記載があり、試しに打ってみることに。
参考サイト
コマンド:python3 manage.py sqlmigrate <アプリ名> <マイグレーションファイル名>
BEGIN;
Create model CartModel
CREATE TABLE "ec_cartmodel" ("created_at" timestamp with time zone NOT NULL, "updated_at" timestamp with time zone NOT NULL, "cart_id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY);
Create model CartItemModel
CREATE TABLE "ec_cartitemmodel" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "created_at" timestamp with time zone NOT NULL, "updated_at" timestamp with time zone NOT NULL, "quantity" integer NOT NULL, "cart_id_id" bigint NOT NULL, "name_id" bigint NOT NULL);
COMMIT;
データ型が定義されてるので上記のCREATE TABLE
コマンドをコピーしてDBコンテナから手動でテーブルを作成すると、、
django_develop=# CREATE TABLE "ec_cartmodel" ("created_at" timestamp with time zone NOT NULL, "updated_at" timestamp with time zone NOT NULL, "cart_id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY);
CREATE TABLE
コマンドが問題なく通った!
\d
コマンドでテーブル一覧を確認するとec_cartmodel
テーブルが作成されている!
django_develop=# \d
List of relations
Schema | Name | Type | Owner
--------+-----------------------------------+----------+----------
public | Ec_OrderdModel | table | postgres
public | Ec_OrderdModel_id_seq | sequence | postgres
public | Ec_ProductModel | table | postgres
public | Ec_ProductModel_id_seq | sequence | postgres
public | ec_cartmodel | table | postgres
public | ec_cartmodel_cart_id_seq | sequence | postgres
管理画面にログインしCart modelsテーブルにログイン
ADD CART MODELからレコードが問題なく追加できることを確認。
Cartテーブルと同様の流れでCartItemテーブルも正常に作成することができました。
事象の原因について
詳細な事象の原因については特定に至ってないですが、コンテナが使い捨てを前提として運用する物なのでコンテナ内でマイグレーションを実行した際にマイグレーションが正常に実行されなくなってしまったのではないか。と推測してます。
参考サイト
まとめ
コンテナを使った開発だとトラブルシュートの難易度が少し上がる気がしますが、コンテナ技術は開発をする上で大変便利なものという理解はしてるので、引き続き学習を続けていきたいと思います。