Database/Postgresql

DB를 먼저 설계하고 django와 연동하기 (2) - migration 후 db 추가 설계 그리고 inspectdb

bluebamus 2023. 12. 7.

github 저장소 : https://github.com/bluebamus/synchronization-test-between-django-and-db

 

1. DB를 먼저 설계하고 django와 연동하기 (1) - 작업 정의

2. DB를 먼저 설계하고 django와 연동하기 (2) - migration 후 db 추가 설계 그리고 inspectdb

3. DB를 먼저 설계하고 django와 연동하기 (3) - inspectdb로 생성된 models.py로 migrations 후 비교

4. DB를 먼저 설계하고 django와 연동하기 (4) - fake를 사용해 migrate 후 models.py 수정 반영하기

5. DB를 먼저 설계하고 django와 연동하기 (5) - view table 테스트

6. DB를 먼저 설계하고 django와 연동하기 (6) - 함수와 lock 사용하기

 

 - django의 모든 시스템을 사용하기 위해서 요구되는 필수 table들을 미리 생성할 필요가 있다. 이러한 작업은 다음과 같은 작업을 기반으로 수행되었다.

 

 1. 프로젝트 생성 및 기본 django 테이블 생성과 추가 테이블 설계 및 생성

   - 프로젝트 생성

python manage.py startproject config .

 

   - postgresql 설정

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "HOST": "127.0.0.1",
        "PORT": "5433",
        "NAME": "sync",
        "USER": "sync",
        "PASSWORD": "1324",
        "CHARSET": "utf8",
        "OPTIONS": {
            "options": "-c search_path=sync_test",
        },
        "CONN_MAX_AGE": 500,
    }
}

 

   - database 스키마 생성

python manage.py makemigrations

 

   - database와 연동

python manage.py migrate

 

   - db에 items, user_order, stock, stock_order 테이블 생성, auth_user 테이블은 생성된 테이블 사용

      - items 테이블의 group에 items_group_idx라는 이름으로 인덱스 추가

 

    - 추가된 테이블을 포함한 전체 테이블 리스트

 

   - 테이블을 추가할 때에는 반드시 Owner를 확인하자

      - 만약 owner를 변경하고자 한다면 다음 방법을 사용하자

ALTER TABLE 테이블명 OWNER TO 새로운_소유자;

 

 2. inspectDB로 변경된 db 스키마를 django에 동기화 

   - inspectdb를 실행한다

py manage.py inspectdb > models.py

 

   - 필요한 table 코드만 확인해보자

class AuthUser(models.Model):
    password = models.CharField(max_length=128)
    last_login = models.DateTimeField(blank=True, null=True)
    is_superuser = models.BooleanField()
    username = models.CharField(unique=True, max_length=150)
    first_name = models.CharField(max_length=150)
    last_name = models.CharField(max_length=150)
    email = models.CharField(max_length=254)
    is_staff = models.BooleanField()
    is_active = models.BooleanField()
    date_joined = models.DateTimeField()

    class Meta:
        managed = False
        db_table = 'auth_user'

class Items(models.Model):
    item_name = models.CharField(max_length=20)
    item_group = models.CharField(max_length=10)
    item_number = models.IntegerField()
    default_order_stock = models.IntegerField()
    created_at = models.DateTimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'items'
        unique_together = (('item_name', 'item_number'),)


class Stock(models.Model):
    item = models.ForeignKey(Items, models.DO_NOTHING)
    item_stock = models.IntegerField()
    discontinued = models.BooleanField()
    discontinued_at = models.DateTimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'stock'


class StockOrder(models.Model):
    item = models.ForeignKey(Items, models.DO_NOTHING)
    admin = models.ForeignKey(AuthUser, models.DO_NOTHING)
    order_quantity = models.IntegerField()
    ordered_at = models.DateTimeField(blank=True, null=True)
    estimated_arrival_time = models.DateTimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'stock_order'


class UserOrder(models.Model):
    order_quantity = models.IntegerField()
    order_number = models.BigIntegerField()
    item = models.ForeignKey(Items, models.DO_NOTHING)
    user = models.ForeignKey(AuthUser, models.DO_NOTHING)
    created_at = models.DateTimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'user_order'

 

 

 3. Table과 models.py의 동기화 분석

   - table에 current_timestamp가 default로 설정되어 있지만 코드에는 설정되어 있지 않다. 

   - models.py의 필드에 아래와 같이 설정을 할 경우, 마찬가지로 table의 default에 설정되지 않는것을 확인하였다.

      - postgresql에서 id는 컬럼 속성의 identity에 'By Default'로 자동 증가가 설정되어 있지만, 그 외 필드들의 default로 설정되어야 할 값들은 아무것도 설정이 되어 있지 않았다.

         - mysql 또한 같은 상황인 것을 확인하였으며, 이로인해 default 또한 django 에서 코드로 커버가 되는 항목이지 databse의 default 파라미터로 설정되는 것이 아니다는 것을 확인할 수 있다. 

from django.db import models

class MyModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    # 다른 필드들 정의

 

   - FK와 unique 설정은 제대로 가져와진다. 하지만 index는 가져오지 못한다.

   - 반대로 model에서 아래와 같이 index 설정을 하면 table에 설정이 된다.

from django.db import models

class Item(models.Model):
    # 필드 정의

    class Meta:
        indexes = [
            models.Index(fields=['field_name1']),
            models.Index(fields=['field_name2'], name='custom_index_name'),
        ]

 

 4. 다음 작업

   - 새로운 프로젝트를 만들고 app을 추가하여 기본 class들은 전부 삭제하고 추가된 table만 정의한다.

   - 필드의 파라미터 등을 이용해 table에 설정된 값들을 그대로 정의한다.

   - databse의 스키마를 새로 만들고 migration 실행 후 두 스키마의 테이블 구성을 비교해본다.

댓글