반응형

백엔드 Back-end 95

셸 스크립트로 MySQL 데이터베이스 원격에서 로컬 데이터베이스로 복사하기

백엔드 개발을 하다보면 QA용 테스트 데이터베이스를 내 컴퓨터 로컬 데이터베이스로 복사를 자주하게 된다. DBeaver, Workbench 등 데이터베이스 클라이언트 프로그램을 이용해도 되지만 번거롭다. 매번 복사할 데이터베이스를 선택하고, export 누르고, 다시 로컬 데이터베이스에 접속해서 import 누르는 과정을 진행하는데도 시간이 꽤 걸린다. 자칫 잘못하면 로컬 데이터베이스를 QA 테스트 데이터베이스로 거꾸로 복사할 수도 있으니 집중해야 해서 더 피곤하다. 그래서 셸 스크립트로 만들었다. #!/bin/bash # 원격 데이터베이스 MYSQL_HOST="" MYSQL_USER="" MYSQL_PASSWORD="" # 로컬 데이터베이스 MYSQL_HOST_LOCAL="127.0.0.1" MYSQL..

Q. 장고에 gunicorn을 같이 써야 하는 이유는?

A. CPU가 여러개인 환경에서는 훨씬 빠르기 때문이다. 그밖에 HTTPS 적용 등 다양한 기능을 활용할 수 있다. 먼저 이 글 Q. NGINX, gunicorn없이 Django장고만 실행 가능할까? 을 참고해서 gunicorn 없이 테스트를 진행하자. gunicorn 설치하고 실행하기 아래 명령어를 참고해서 gunicorn을 설치하고 실행하자. $ pip install gunicorn $ sudo GUNICORN_CMD_ARGS="--bind=0.0.0.0:80 --workers=3" ./venv/bin/gunicorn config.wsgi:application 설정 설명을 보면 추천 worker수는 CPU core수의 2~4배다. Worker Processes workers Command line: ..

Q. NGINX, gunicorn없이 Django장고만 실행 가능할까?

A. 보통은 Nginx - gunicorn - Django로 구성한다. 보통 권장되지 않지만 Django장고만 실행할 수도 있다. 로컬에서 테스트할 때처럼 하면 되고 차이점은 서버 실행 명령어다. 실행 방법 직접 해보면 잘 된다. 장고 실행하기 우선 EC2에 장고를 설치하고 실행해보자. django_minimal을 참고하자. 아래 실행 환경은 EC2 Ubuntu 20.04(t2.micro)다. EC2에 접속해서 아래처럼 진행하면 된다. $ sudo apt update $ sudo apt install python3.8-venv $ mkdir django_minimal $ cd django_minimal$ $ python3 -m venv venv $ source ./venv/bin/activate $ pi..

Q. MongoDB 데이터베이스 백업Dump과 복원Restore 하는 방법은?

A. mongodump와 mongorestore 명령어를 활용하면 된다. EC2에 아래 글을 참고해서 우선 MongoDB를 설치하자. 참고할 글: Q. AWS EC2에 MongoDB 설치하고 외부 접속 가능하게 만드는 방법은? 테스트 데이터 입력하기 MongoDB Compass로 접속해서 아래처럼 test란 데이터베이스를 만들고 collection이란 collection을 만들어서 아무 데이터나 하나 넣었다. mongodump 어드민으로 사용자를 추가한 경우 --authenticationDatabase="admin" 를 추가해줘야 한다. mongodump --host="3.35.154.100:27017" --username="taptorestart" --password="password" --db="te..

Q. 유명 개발자들은 파이썬 테스트 코드를 어떻게 작성할까?

A. 사례를 찾아보면 진짜 생각보다 간단하게 짠다. 테스트 코드 작성 어렵다. 작성하면서도 이게 과연 올바른가 의심될 때가 있다. 이럴 때는 유명 개발자들은 어떻게 하는지 찾아보는 것만으로도 큰 도움이 된다. 게다가 개발 바닥은 쉽게 찾을 수 있으니! 구글 구글부터 살펴보자. github에서 구글로 들어가서, 언어는 파이썬, 정렬은 별개수로 하자. 목록 상단에 있는 google / jax를 골랐다. 여기 들어가니 tests 디렉터리가 있다! 여러 테스트 파일 중 core_test.py를 보자. tree_flatten이란 함수를 테스트하는 코드는 아래가 다다. 값은 직접 입력했고, 입력한 값은 아주 간단한 것을 볼 수 있다. 10개가 아니라 1개다. def test_tree_flatten(self): fl..

Q. 장고 ORM에서 OneToOneField와 ForeignKey에 unique=True를 한 경우 서로 어떤 차이가 있을까?

A. 데이터베이스 상으로는 차이가 없다. 예제 코드는 DRF CRUD 예제 프로젝트를 활용했다. 데이터베이스 설정만 MySQL로 변경했다. 변경한 예는 아래와 같다. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'root', 'PASSWORD': 'password', 'HOST': '127.0.0.1', 'PORT': '3306', } } 환경은 장고는 3.2.12 파이썬은 3.8 버전이다. ForeignKey 그냥 ForeignKey 모델이다. from django.db import models class Category(models.Model): name = models.CharField..

frisby.js로 REST API 서버 테스트 하기

frisby.js란? "Frisby makes REST API testing easy, fast, and fun." - frisby.js 소개에서 "Frisby는 REST API 테스트를 쉽고, 빠르고 재미있게 만든다." REST API 테스트용 라이브러리다. 어떤 언어로 되어 있나? 자바스크립트 기반이고, 테스트를 실행하기 위해서 Jest를 사용한다. 테스트 코드 자체가 반복적이기 때문에 엄청 높은 수준의 자바스크립트 지식을 필요로 하지는 않는다. 자바 기반 스프링부트나 파이썬 기반 장고 등 다른 언어로 API 서버를 개발해도 쉽게 frisby.js로 테스트 코드를 짤 수 있다. 언제 사용하는가? API 서버를 테스트할 때 사용한다. Postman 같은 API 테스트 플랫폼과 같은 용도다. 장점은 코드..

데이터베이스 예제를 보면서 참고하기

관계형 데이터베이스를 설계 하다보면 다른 사람들은 어떻게 설계하는지 궁금해진다. 특히 전문가들은 어떻게 하는지 궁금해진다. 그때는 예제를 많이 보면 도움이 될 수 있다. Postgresql wiki Sample Databases 에 가면 무료 예제 데이터베이스를 살펴볼 수 있다. 무료 예제 데이터베이스 스키마를 참고하기 편하게 여기에 taptorestart/database-schema-examples 로 정리 중이다.

DRF(Django Rest Framework) API 서버에 requests로 PUT할 때 나타나는 이상현상

BooleanField로 설정한 필드의 값이 만약 default=false라면 모두 false로 변경된다. 간단히 테스트를 위해서 DRF로 API 서버를 만들었다. 주요 모델은 아래처럼 생겼다. (예제코드: DRF CRUD) 모델 class Category(models.Model): name = models.CharField(max_length=200) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Beverage(models.Model): name = models.CharField(max_length=200) category = models.ForeignKe..

Lombok @Getter @NoArgsConstructor @Builder @AllArgsConstructor 실제 빌드된 클래스로 살펴보기

Lombok을 사용하면 Getter나 Setter처럼 정말 많이 쓰는 작업을 자동화할 수 있어서 편하다. 테스트를 위해서 User 클래스 하나를 만들었다. 아래처럼 생겼다. package com.test; public class User { private Long id; private String name; private String password; public void update(String name, String password) { this.name = name; this.password = password; } } 빌드해보자. 빌드를 하면 build 디렉터리 아래 class 파일이 생성된다. 원래는 알아볼 수 없게 생겼다. IntelliJ IDEA 상에서 빌드된 파일을 클릭하면 디컴파일러를 통..

Q. API 서버에서 인메모리 데이터베이스를 캐시cache로 쓰면 얼마나 빨라질까?

A. 응답을 받는데 1초가 걸리던 엔드포인트가 있다면, 100배 넘게 빨라질 수 있다! 처음에 1초 걸리던 게, 그 다음에는 0.0003초 걸렸다. 3000배 이상 빨라진 것이다. 컴퓨터 성능에 따라 다르지만 보통 100배 이상 빨라질 수 있다. 위 캡쳐화면을 통해서 왜 인메모리 데이터베이스를 캐시로 써야 하는지 쉽게 이해할 수 있다. 캐시를 쓰는 것만으로도 성능을 엄청나게 빠르게 할 수 있으니, 당연히 써야 한다. 구현 방법 구현 방법은 간단하다. redis 같은 메모리 데이터베이스에 endpoint와 파라미터 전체 url을 키로 넣고, 응답을 값으로 해서 저장하는 식이다. 그럼 완전히 동일한 endpoint와 파라미터로 다시 요청이 왔을 때 메모리 상에 저장해둔 응답을 바로 보내주면 아주 빨리 처리할..

Q. kafka에서 group_id를 설정하면 어떻게 될까?

A. group id가 같을 경우 한 클라이언트에서만 메시지를 소비(consume)할 수 있다. 테스트를 위한 코드: python kafka - producer and consumer 아래처럼 group_id를 설정한 경우에 consumer를 터미널 창을 두 개 띄워서 테스트할 경우 한쪽에서만 메시지를 받을 수 있다. import kafka consumer = kafka.KafkaConsumer(bootstrap_servers='localhost:9092', group_id='test-group') consumer.subscribe(topics=['quickstart-events']) for msg in consumer: print(msg) group_id를 설정하지 않은 경우에는 양쪽에 같은 메시지가 ..

백엔드 Back-end 2022.04.11

FastAPI 바탕 프로젝트: 이메일 회원 가입과 JWT 토큰, MySQL 사용

Full Stack FastAPI and PostgreSQL - Base Project Generator, MIT License을 바탕으로 다른 프로젝트의 시작점이 될 수 있는 베이스 프로젝트를 만들었다. 주요 기능 주요 기능은 다음과 같다. - 이메일과 비밀번호로 회원가입 - 비밀번호 암호화 - 관리자(superuser) 생성 - JWT 토큰으로 사용자 식별 및 권한 제어 - ORM 적용 - MySQL 사용 프로젝트 루트 디렉터리에 .env 파일을 만들어서 저장해둬야 정상 작동한다. .env 파일 예는 아래와 같다. 데이터베이스 정보와, 비밀키, 첫 관리자 생성 정보다. USERNAME=admin PASSWORD=verysecret HOST=localhost PORT=3306 DATABASE=app S..

Q. FastAPI에서 pytest 할 때 ModuleNotFoundError: No module named 'fastapi' 오류 해결 방법은?

A. python -m pytest 라고 실행하거나 터미널 창을 닫았다가 다시 열고 실행하면 된다. 아래처럼 에러가 나타난다. 해결 방법은 터미널창을 닫았다가 다시 열고 실행하면 된다. 터미널창이나 PyCharm 같은 IDE를 닫고 다시 실행하기 귀찮다면 python -m pytest 라고 실행하면 정상 작동한다. pytest 설치 직후에 pytest.ini 파일을 만들고 아래와 같은 test.py를 실행해 보면 pytest.ini [pytest] addopts = -s test.py import sys def test(): print(sys.path) assert True 해당 디렉터리 아래 만들어 놓은 파이썬 가상환경 venv 내의 site-packages가 없다. 그래서 fastapi 모듈이 없다고..

Q. HTTP PUT 메소드와 PATCH 메소드의 차이는?

A. PUT은 새로운 리소스를 생성하거나 대상 리소스를 나타내는 데이터를 대체, PATCH는 일부 수정할 때 사용한다. (출처: MDN Web Docs PUT, MDN Web Docs PATCH) 위 설명에서 중요한 건 리소스를 생성도 한다는 점이다. 대상 리소스가 없으면 PUT은 새로 생성한다. 있다면 바꾸고. PUT은 없으면 Add, 있다면 Replace 교체 느낌이다. PATCH는 수선 고치는 Update 느낌이다. 실제 코드에서는 PUT을 PATCH처럼 쓰는 경우를 많이 볼 수 있다. 유명한 개발자들도 그렇게 쓰는 경우도 발견할 수 있다. PUT을 PATCH처럼 쓰는 예 (출처: full-stack-fastapi-postgresql) @router.put("/me", response_model=s..

백엔드 Back-end 2022.02.27

Q. FastAPI에서 MySQL unsigned integer 길이 11로 하는 방법은?

A. Column(INTEGER(display_width=11, unsigned=True), primary_key=True, index=True)로 설정하면 된다. 위처럼 설정하기 위해서는 INTEGER를 불러와야 한다. 아래 코드가 그 예이다. from sqlalchemy.dialects.mysql import INTEGER class User(Base): __tablename__ = "users" id = Column(INTEGER(display_width=11, unsigned=True), primary_key=True, index=True) email = Column(String(255), unique=True, index=True) hashed_password = Column(String(255..

Q. NestJS에서 앱이 구동될 때 실행되도록 하는 방법은?

A. onApplicationBootstrap()을 활용하면 된다. 참고: NestJS Lifecycle Events NestJS에서는 의존성 주입을 많이 쓰기 때문에, 의존성 주입하는 클래스를 new로 인스턴스를 생성해서 main.ts에서 실행하기는 쉽지 않다. 등록된 모듈 파일 중 하나에 아래 코드를 넣어보자. onApplicationBootstrap() { console.log('Test onApplicationBootstrap'); } 그리고 npm run start:dev를 실행하면 쭉 뜨는 사이에 위 로그가 찍히는 것을 볼 수 있을 것이다.

Q. NestJS gRPC 클라이언트 구현에서 "The invalid gRPC service (service not found)" 에러 원인은?

A. service명이 잘못 되어서 그렇다. 여기서 service명은 gRPC 서비스명이다. 예를 들어서 아래와 같은 hero.proto 파일이 있다. (출처: nestjs microservices gRPC) syntax = "proto3"; package hero; service HeroesService { rpc FindOne (HeroById) returns (Hero) {} } message HeroById { int32 id = 1; } message Hero { int32 id = 1; string name = 2; } 여기서 서비스명은 'HeroesService'이다. 팩키지명은 'hero'이다. service ABCD { rpc FindOne (HeroById) returns (Hero) ..

FastAPI 디렉터리 구조를 어떻게 하는 게 좋을까?

프로젝트명으로 저장소를 만들고 클론을 떠서 로컬에서 개발을 시작하고 나면, 디렉터리 구조부터가 고민이 되기 시작한다. django나 nestjs 등의 경우 CLI 명령어를 치면 자동으로 쭉 디렉터리와 기본 파일들을 만들어준다. 그런 경우 고민이 덜하다. 그 틀에 맞춰서 따라가면 되니까. 하지만 FastAPI의 경우 아직 그런 기능이 없는 거 같다. PyCharm을 쓰고 있어서 새 프로젝트 만들기를 누르고 FastAPI를 선택했지만 별 거 없다. 그냥 main.py와 test_main.http 파일 두 개와 venv 디렉터리만 생기고 끝이다. FastAPI로 개발할 때 과연 어떤 디렉터리 구조가 좋을까? FastAPI 개발자인 Sebastián Ramírez(tiangolo)의 예제 프로젝트가 있다. fu..

Q. Postman으로 POST해서 생성한 id 받아서 PATCH DELETE 테스트할 수 있을까?

A. 있다. 가능하다. Tests 탭을 눌러서 코드를 입력하면 환경변수에 등록할 수 있다. 코드 예는 아래와 같다. var jsonData = pm.response.json(); pm.environment.set('article_id', jsonData['id']); pm은 포스트맨 객체이고, response는 응답이다. 거기서 json을 jsonData로 저장한 것이고, 새로 생성된 'id'를 받아서 'article_id'로 환경변수에 저장하게 된다. 이 해당 환경변수를 다음 PATCH나 DELETE에 사용하면 된다. 아래처럼 id 입력 자리에 {{article_id}}를 입력하면 환경변수로 저장한 article_id를 불러오게 되고 방금 POST한 데이터를 수정할 수 있게 된다. PATCH http:..

반응형