나는 이렇게 학습한다/Debug 14

SQLAlchemy _ ForeignKey 필드에 name 을 넣어주어야 Alembic 이 downgrade 해줌

한 줄 요약 *ForeignKey 필드에 name을 넣어주어야 *Alembic 이 *downgrade 해줌. *ForeignKey 필드는 다른 테이블의 기본 키를 참조하는 테이블 필드를 의미함 *Alembic은 Python용 데이터베이스 마이그레이션 도구임 *downgrade는 이전 version으로 되돌리는 것을 의미함 문제상황 부모 record 를 지우면 자식 record 도 지워지도록, 자식 parent_id 필드에 ondelete="CASCADE" 옵션을 추가했다. class Child(Base): __tablename__ = "child" id = sa.Column(UUID(as_uuid=True), primary_key=True) parent_id = sa.Column( UUID(as_uuid..

pytest _ 테스트 코드에서 현재 시간 바꾸는 방법

현재 시간을 바꾸는 이유 테스트 코드를 작성하다 보면 현재 시간이 특정 시간을 넘겼을 때 정상적으로 코드가 수행되는지 테스트하고 싶을 때가 있다. 예를 들어 만료일자가 있고 오늘 날짜가 만료일자를 지나면 서비스를 중단하는 로직이 있다고 하자. 이를 어떻게 테스트할 수 있을까? 오늘 날짜가 아직 만료일자를 지나지 않았기 때문에 이를 테스트하기 위해서는 오늘 날짜 혹은 만료일자를 mock으로 대체하여 구현해야 한다. 하지만 mock을 직접 구현하는 데에는 코스트가 들기 때문에 아무래도 꺼려지는 방법이다. 만약 당신이 pytest를 사용한다면 pytest-freezegun 라이브러리를 이용해 이 문제를 쉽게 해결할 수 있다. pytest에서 시간 freeze 하는 방법 먼저 pytest-freezegun 라이..

pytest _ 비동기 테스트 실행하기 (feat. auto 모드)

pytest 에서 async 테스트 함수를 실행하는 방법에는 'strict 모드' 와 'auto 모드' 가 있다. 오늘은 손쉽게 비동기 테스트를 할 수 있는 'auto 모드' 에 대해 알아보자. 먼저 pytest-asyncio 를 설치한다. pip install pytest-asyncio 아래 1번과 2번 중에 하나를 선택하여 파일과 코드를 추가한다. 1번 # pytest.ini [pytest] asyncio_mode = auto 2번 # pyproject.toml [tool.pytest.ini_options] asyncio_mode = "auto" 이것으로 'auto 모드' 설정이 끝났다. auto 모드는 pytest.ini 혹은 pyproject.toml 파일에 옵션 코드를 추가하여 async 테스트..

python _ traceback 에러 메시지 핸들링하기

traceback 이란? 파이썬으로 개발을 하다보면 traceback 이란 단어를 많이 접하게 된다. traceback은 역 추적 이란 뜻으로 해당 에러가 어디서부터 발생했는지 우리에게 알려준다. 예를들어 다음처럼 빈 dictionary에 “값 내놔” 라는 key를 호출하면, 해당 key가 없기 때문에 KeyError가 발생한다. dict = {} dict["값 내놔"] Traceback (most recent call last): File "example.py", line 2, in dict["값 내놔"] KeyError: '값 내놔' 위의 메시지로 보자면 KeyError가 line 2에서 발생했음을 알 수 있다. 이처럼 에러 메시지는 디버깅을 할 때 매우 유용하다. 하지만 에러가 언제 발생할지 우리는..

pytest _ pytest-cov로 coverage 확인하기(실습)

GitHub - Daco2020/pytest-cov-practice: Repository for practicing pytest-cov Repository for practicing pytest-cov. Contribute to Daco2020/pytest-cov-practice development by creating an account on GitHub. github.com (실습에 사용하는 소스코드는 위 링크에서 확인할 수 있습니다.) pytest-cov 란? pytest-cov는 --cov 옵션 추가하여 테스트 대상의 coverage를 확인할 수 있습니다. 사용자는 coverage 수치를 통해 테스트의 적용범위를 파악할 수 있습니다. 실습 방법 레포지토리 복사 git clone https://g..

pytest _ mock 사용하여 테스트 코드 작성하기

mock이란? 쉽게 말해 ‘가짜’ 데이터라고 이해하면 된다. 예를 들어 테스트 코드를 작성할 때, 실제 모듈과 유사하게 동작하는 가짜 데이터를 만들어 사용할 수 있다. ‘가짜’ 데이터인 ‘mock’을 왜 사용하는 걸까? 테스트하려는 함수가 10초 이상의 연산 시간이 필요한 모듈에 의존하고 있다고 가정해보자. 우리는 해당 함수를 테스트할 때마다 매번 10초를 기다려야 한다. 이는 개발 생산성을 크게 저하시킬 것이다. 의존하고 있는 모듈로 인해 본 코드를 테스트하기 어려울 때, mock을 사용하면 해당 모듈을 실행하지 않고도 해당 테스트를 검증할 수 있다. 우리는 모듈의 응답을 mock으로 대체함으로써 본 코드의 테스트에 집중할 수 있다. 이처럼 성능 저하, 비용 등 불필요한 리소스 발생이 예상될 때, 일반..

docker-compose 작성하면서 생긴 이슈 세 가지 (feat. m1)

docker-compose를 이용해 app과 db를 각각 컨테이너로 구현해보고자 했다. 도커를 처음 사용하다 보니 여러가지 문제들이 있었는데 그 중에서 가장 애먹었던 세 가지 이슈에 대해서 적어본다. 이슈1. 도커 빌드 중에 asyncpg만 유독 설치되지 않는 문제가 있었다. 원인 - 정확히는 알기 어려우나 m1 관련 이슈로 보인다. 해결 - 빌드 과정에서 gcc를 추가 설치하여 해결할 수 있었다. # Dockerfile 에 추가 RUN apt-get install -y gcc gcc는 ‘다양한 프로그래밍 언어를 위한 컴파일러’ 라고 한다. 자세한 내용은 위키를 참고하기 바란다. 참고 링크 Error with pip install in Docker on Mac M1 when using Slim distr..

VSCode _ 디버깅하는 방법 (feat. Python - FastAPI)

print로 디버깅? 서버 런타임 중에 버그가 발생했다고 가정해보자. 내가 원하는 값을 반환해주어야 하는데 엉뚱한 값이 나온다. 버그를 찾아 고치기 위해 작성된 코드를 보지만 어디서부터 잘못된 건지 모르겠다. 그럴 때 흔히 하는 방법이 print()로 코드 중간중간을 출력하는 것이다. 의심스러운 지점에 print를 배치하고 내가 생각한 대로 작동하는지 출력해본다. 하지만 이 방법은 리소스가 많이 든다. 개발자가 직접 코드를 작성해야하고 상태나 변수명을 직접 호출해야 한다. 설령 버그를 발견하고 고치더라도 print 지우는 것을 까먹어 불필요한 코드까지 커밋해버리기도 한다...ㅜㅜ 다행히도 VSCode는 우리가 손쉽게 디버깅 할 수 있도록 도와준다. 이번 글에서는 Python - FastAPI 서버를 기준..

SQLAlchemy _ NotSupportedError(InvalidCachedStatementError) 에러 해결

AsyncSessionNotSupportedError, InvalidCachedStatementError 테스트 코드를 작성하는 중에 에러가 발생했다!! 에러 메시지는 다음과 같다. """ sqlalchemy.exc.NotSupportedError: (sqlalchemy.dialects.postgresql.asyncpg.InvalidCachedStatementError) : cached statement plan is invalid due to a database schema or configuration change (SQLAlchemy asyncpg dialect will now invalidate all \\ prepared caches in response to this exception) E [..

컬럼 속성 변경 후 alembic migration할 때 ‘None’ 생기는 현상

테이블 컬럼의 속성을 변경하고 alembic migration 할 때 version 파일에 None이 생기는 현상을 발견했습니다. 의도 일단 저는 stock 테이블에서 code와 name컬럼의 속성을 unique로 변경하고자 했습니다. # models.py class Stock(Base): __tablename__ = "stock" id = Column(Integer, primary_key=True, autoincrement=True) code = Column(String(50), unique=True) # unique=True 속성 추가 name = Column(String(50), unique=True) # unique=True 속성 추가 market = Column(ENUM("KOSPI", "KOS..