📮4. Django DB 연결 대기 커스텀 커맨드 제작 및 GitHub Actions 적용기

2025. 6. 9. 18:20·프로젝트

Django DB 연결 대기 커스텀 커맨드 제작 및 GitHub Actions 적용기


🎯 Mission 1: DB 연결을 위한 커스텀 명령어 생성하기

1️⃣ core 앱 생성

python manage.py startapp core

2️⃣ core 앱을 settings.py에 등록

# config/settings/base.py

INSTALLED_APPS = [
    # ...
    'core',  # ✅ core 앱 추가
]

3️⃣ core/management/commands/wait_for_db.py 생성

mkdir -p core/management/commands
touch core/management/__init__.py
touch core/management/commands/__init__.py
touch core/management/commands/wait_for_db.py

4️⃣ 초기 wait_for_db.py 코드 작성

# 잘못된 초기 버전
import time
from django.db import connections
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand
from psycopg2 import OperationalError as Psycopg2OpError

class Command(BaseCommand):
    help = 'PostgreSQL DB가 준비될 때까지 기다립니다.'

    def handle(self, *args, **options):
        for i in range(10):
            self.stdout.write(f'Try {i+1}: Waiting for database...')
            try:
                connection = connections['default']
                if connection:
                    self.stdout.write(self.style.SUCCESS('✅ PostgreSQL DB 연결 성공!'))
                    return
            except (Psycopg2OpError, OperationalError):
                self.stdout.write(self.style.WARNING("⚠️ DB 연결 실패, 재시도 중..."))
                time.sleep(1)
        self.stdout.write(self.style.ERROR('❌ DB 연결 실패!'))

🚨 문제점: connections['default']는 객체 생성만 하며 실제 연결 테스트를 하지 않음.
DB가 꺼져 있어도 성공 메시지 출력되는 문제 발생.


✅ 수정된 wait_for_db.py

# 수정된 최종 버전
import time
from django.db import connections
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand
from psycopg2 import OperationalError as Psycopg2OpError

class Command(BaseCommand):
    help = 'PostgreSQL DB가 준비될 때까지 기다립니다.'

    def handle(self, *args, **options):
        max_attempts = 10
        wait_seconds = 1

        self.stdout.write(self.style.NOTICE('🚀 DB 연결 시도 시작!'))

        for attempt in range(1, max_attempts + 1):
            try:
                db_conn = connections['default']
                cursor = db_conn.cursor()   # ✅ 진짜 연결 시도
                cursor.execute('SELECT 1')  # ✅ 쿼리 실행으로 실제 연결 확인
                self.stdout.write(self.style.SUCCESS('✅ PostgreSQL DB 연결 성공!'))
                return
            except (Psycopg2OpError, OperationalError):
                self.stdout.write(
                    self.style.WARNING(f'⚠️  {attempt}회차 연결 실패. {wait_seconds}초 후 재시도...')
                )
                time.sleep(wait_seconds)

        self.stdout.write(self.style.ERROR('❌ DB 연결 실패! 최대 재시도 횟수 초과.'))

💡 개선된 포인트

  • cursor.execute('SELECT 1') 추가로 진짜 DB 연결 확인
  • 연결 실패 시 재시도 후 최대 10회 실패 시 종료

🎯 Mission 2: GitHub Actions에서 wait_for_db 적용하기

1️⃣ 기존 .github/workflows/checks.yml 문제

- name: Build and start containers
  run: |
    docker compose up -d --build
    sleep 10  # ❌ 고정 시간 대기 (DB 준비 안 되면 실패)

🚨 문제점: sleep 10은 DB가 준비되었는지 모르고 단순히 10초만 기다림.
만약 DB가 10초 안에 준비 안 되면 CI 실패.


2️⃣ 수정된 .github/workflows/checks.yml

name: Code Quality Checks

on:
  push:
    branches:
      - '**'
  pull_request:

jobs:
  ci:
    runs-on: ubuntu-latest

    services:
      my-db:
        image: postgres:14
        env:
          POSTGRES_USER: ${{ secrets.PG_USER }}
          POSTGRES_PASSWORD: ${{ secrets.PG_PASSWORD }}
          POSTGRES_DB: ${{ secrets.PG_NAME }}
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Build and start containers
        run: |
          docker compose up -d --build

      - name: Wait for Database
        run: docker compose exec my-django python manage.py wait_for_db

      - name: Check code formatting with isort
        run: docker compose exec my-django isort . --check --diff

      - name: Check code formatting with black
        run: docker compose exec my-django black . --check

      - name: Apply migrations
        run: docker compose exec my-django python manage.py migrate

      - name: Run tests
        run: docker compose exec my-django python manage.py test

      - name: Cleanup containers
        run: docker compose down --volumes --remove-orphans

💡 개선된 포인트

  • sleep 10 삭제
  • wait_for_db 커맨드를 실행하여 DB가 완전히 준비될 때까지 대기
  • DB가 준비되지 않으면 자동 재시도하고 실패 시 에러 반환

✅ 우리가 디버깅하며 수정한 핵심 요약

문제수정
connections['default']만 가져오면 DB 없이도 성공 cursor.execute('SELECT 1')로 진짜 연결 확인
GitHub Actions에서 sleep 10 고정 대기 wait_for_db로 DB 준비될 때까지 정확하게 대기
 

🏁 최종 결과

  • 로컬에서 DB 꺼진 상태에서도 정상적으로 10번 재시도 확인.
  • GitHub Actions에서도 확실한 DB 준비 완료 후 테스트 진행 가능.
  • CI/CD 실패율 대폭 감소 🎯

'프로젝트' 카테고리의 다른 글

🚩[3단계-1] 내 프로젝트 맞춰 만들어보는 API 스펙  (0) 2025.06.09
📌 [3단계] DRF(Django REST Framework) 설치 및 Docker 적용  (0) 2025.06.09
📮 3. Django ORM을 활용하여 Model 생성하기  (1) 2025.06.09
📮 3. ERD를 구성 Mermid 활용  (0) 2025.06.09
📮2. 데이터베이스 스키마 설계  (1) 2025.06.09
'프로젝트' 카테고리의 다른 글
  • 🚩[3단계-1] 내 프로젝트 맞춰 만들어보는 API 스펙
  • 📌 [3단계] DRF(Django REST Framework) 설치 및 Docker 적용
  • 📮 3. Django ORM을 활용하여 Model 생성하기
  • 📮 3. ERD를 구성 Mermid 활용
Chansman
Chansman
안녕하세요! 코딩을 시작한 지 얼마 되지 않은 초보 개발자 찬스맨입니다. 이 블로그는 제 학습 기록을 남기고, 다양한 코딩 실습을 통해 성장하는 과정을 공유하려고 합니다. 초보자의 눈높이에 맞춘 실습과 팁, 그리고 개발하면서 겪은 어려움과 해결 과정을 솔직하게 풀어내려 합니다. 함께 성장하는 개발자 커뮤니티가 되기를 바랍니다.
  • Chansman
    찬스맨의 프로그래밍 스토리
    Chansman
  • 전체
    오늘
    어제
    • 분류 전체보기 (807)
      • Python (32)
      • 프로젝트 (116)
      • 과제 (25)
      • Database (40)
      • 멘토링 (11)
      • 특강 (37)
      • 기술블로그 (42)
      • 기술블로그-Fastapi편 (33)
      • 기술블로그-Django편 (154)
      • 기술블로그-Flask편 (36)
      • AI 분석 (5)
      • HTML & CSS (31)
      • JavaScript (17)
      • AWS_Cloud (21)
      • 웹스크래핑과 데이터 수집 (14)
      • Flask (42)
      • Django (77)
      • Fastapi (16)
      • 연예 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    classaction
    remittance
    newpoliticalparty
    urbantrends
    lawsuitculture
    btsreunion
    btscomeback
    chinanightlife
    basalcellcarcinoma
    titaniumcase
    youngprofessionals
    livebroadcast
    RM
    travel ban
    homebartrend
    global politics
    hotcoffeecase
    chatgpterror
    life reflection
    college reunions
    self-growth
    smartphonedurability
    trumpmuskclash
    btsdischarge
    bts
    gpterror
    americaparty
    americanlaw
    뷔
    btsjungkook
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Chansman
📮4. Django DB 연결 대기 커스텀 커맨드 제작 및 GitHub Actions 적용기
상단으로

티스토리툴바