소개

REST API 서버는 최근 웹 개발에서 매우 중요한 역할을 합니다. Python Flask는 간단하고 빠르게 REST API 서버를 만드는 데에 매우 적합한 프레임워크입니다. 이 글에서는 Python Flask를 이용해 REST API 서버를 어떻게 만드는지에 대해 알아보겠습니다.

목차

  1. Flask 소개
  2. REST API란?
  3. Flask로 REST API 서버 만드는 방법
    1. Flask 설치하기
    2. Flask 라우팅
    3. HTTP Methods
    4. JSON 데이터 전송
    5. REST API 응답 처리
    6. 예외 처리
    7. RESTful API
  4. Flask RESTful 사용하기
    1. Flask-RESTful 설치하기
    2. Flask-RESTful Resource
    3. Flask-RESTful Request Parsing
    4. Flask-RESTful Marshmallow
  5. Flask REST API 서버 보안
    1. JWT(Json Web Token) 인증
    2. Flask-HTTPAuth

1. Flask 소개

Flask는 Werkzeug 툴킷과 Jinja2 템플릿 엔진을 기반으로한 마이크로 웹 프레임워크입니다. Flask는 빠르고 간단한 구성과 디자인을 가지고 있습니다. Flask는 확장성과 유연성이 높아서 다양한 기능을 제공하면서도 쉽게 사용할 수 있습니다.

2. REST API란?

REST (Representational State Transfer)는 분산 시스템에서 구현할 수 있는 아키텍처 스타일입니다. REST API는 HTTP 프로토콜을 이용하여 웹 어플리케이션에서 데이터를 주고 받는 방식 중 하나입니다. REST API는 자원(resource)을 정의하고, 자원에 대한 행위(method)를 구분하여 정의합니다.

3. Flask로 REST API 서버 만드는 방법

3.1 Flask 설치하기

Flask를 사용하기 위해서는 우선 Flask를 설치해야 합니다. 가상환경을 이용하는 것을 권장합니다.

    pip install Flask

3.2 Flask 라우팅

Flask에서는 URL 패턴을 사용하여 함수를 연결합니다. 이를 라우팅(Routing)이라고 합니다.

    from flask import Flask

    app = Flask(__name__)

    @app.route('/')
    def index():
        return 'Hello, World!'

3.3 HTTP Methods

HTTP Method는 REST API에서 자원에 대한 행위를 정의합니다. Flask에서는 HTTP Method에 따라 다르게 처리됩니다.

    from flask import Flask, request

    app = Flask(__name__)

    @app.route('/example', methods=['GET'])
    def example():
        return 'GET method'

    @app.route('/example', methods=['POST'])
    def example():
        return 'POST method'

    @app.route('/example', methods=['PUT'])
    def example():
        return 'PUT method'

    @app.route('/example', methods=['DELETE'])
    def example():
        return 'DELETE method'

3.4 JSON 데이터 전송

REST API에서는 데이터를 주고 받을 때 JSON 데이터 형식을 사용하는 것이 일반적입니다. Flask에서는 JSON 데이터를 쉽게 전송할 수 있는 jsonify 함수를 제공합니다.

    from flask import Flask, jsonify, request

    app = Flask(__name__)

    @app.route('/example', methods=['POST'])
    def example():
        data = request.get_json()  # JSON 데이터 받아오기
        result = {'message': 'success'}
        return jsonify(result)

3.5 REST API 응답 처리

REST API에서는 HTTP 상태 코드를 이용하여 응답을 처리합니다. Flask에서는 make_response 함수를 이용하여 HTTP 상태 코드와 함께 응답을 전송할 수 있습니다.

    from flask import Flask, jsonify, make_response

    app = Flask(__name__)

    @app.route('/example', methods=['GET'])
    def example():
        data = {'key': 'value'}
        response = make_response(jsonify(data))
        response.status_code = 200  # HTTP 상태 코드 설정
        return response

3.6 예외 처리

REST API에서는 예외 처리가 매우 중요합니다. Flask에서는 예외 처리를 위해 abort 함수를 제공합니다.

    from flask import Flask, abort

    app = Flask(__name__)

    @app.route('/example/<int:id>', methods=['GET'])
    def example(id):
        if id == 0:
            abort(404)  # 404 에러 발생
        return 'success'

3.7 RESTful API

RESTful API는 REST API의 설계 규칙을 따르는 API를 말합니다. Flask에서는 RESTful API를 쉽게 구현할 수 있도록 Flask-RESTful이라는 확장 모듈을 제공합니다.

4. Flask RESTful 사용하기

4.1 Flask-RESTful 설치하기

Flask-RESTful를 사용하기 위해서는 우선 Flask-RESTful을 설치해야 합니다.

    pip install flask-restful

4.2 Flask-RESTful Resource

Flask-RESTful에서는 Resource 클래스를 이용하여 API를 구현합니다.

    from flask import Flask
    from flask_restful import Api, Resource

    app = Flask(__name__)
    api = Api(app)

    class Example(Resource):
        def get(self):
            return {'message': 'success'}

    api.add_resource(Example, '/example')

4.3 Flask-RESTful Request Parsing

Flask-RESTful에서는 Request Parsing을 지원합니다. Request Parsing을 이용하면 요청한 데이터를 쉽게 받아올 수 있습니다.

    from flask import Flask
    from flask_restful import Api, Resource, reqparse

    app = Flask(__name__)
    api = Api(app)

    parser = reqparse.RequestParser()
    parser.add_argument('name', type=str)

    class Example(Resource):
        def get(self):
            args = parser.parse_args()
            return {'name': args['name']}

    api.add_resource(Example, '/example')

4.4 Flask-RESTful Marshmallow

Flask-RESTful에서는 Marshmallow를 이용하여 데이터 검증 및 직렬화를 수행할 수 있습니다.

    from flask import Flask
    from flask_restful import Api, Resource, reqparse
    from marshmallow import Schema, fields, ValidationError

    app = Flask(__name__)
    api = Api(app)

    class ExampleSchema(Schema):
        name = fields.String(required=True)

        def handle_error(self, error, data):
            raise ValidationError(error, data=data)

    example_schema = ExampleSchema()

    class Example(Resource):
        def post(self):
            json_data = request.get_json()
            try:
                data = example_schema.load(json_data)
            except ValidationError as e:
                return {'message': str(e)}, 400
            return {'name': data['name']}

    api.add_resource(Example, '/example')

5. Flask REST API 서버 보안

5.1 JWT(Json Web Token) 인증

REST API 서버에서는 보안이 매우 중요합니다. JWT(Json Web Token) 인증은 REST API 서버에서 자주 사용되는 인증 방식 중 하나입니다. Flask에서는 PyJWT 라이브러리를 이용하여 JWT 인증을 구현할 수 있습니다.

    import jwt
    from flask import Flask, jsonify, request

    app = Flask(__name__)

    @app.route('/login', methods=['POST'])
    def login():
        username = request.json.get('username')
        password = request.json.get('password')
        if username == 'admin' and password == 'password':
            token = jwt.encode({'username': username}, 'secret', algorithm='HS256')
            return jsonify({'token': token.decode('utf-8')})
        else:
            return jsonify({'message': 'Invalid username or password'}), 401

5.2 Flask-HTTPAuth

Flask-HTTPAuth는 Flask에서 인증 처리를 쉽게 구현할 수 있도록 도와주는 확장 모듈입니다.

    from flask import Flask, jsonify
    from flask_httpauth import HTTPTokenAuth

    app = Flask(__name__)
    auth = HTTPTokenAuth(scheme='JWT')

    @auth.verify_token
    def verify_token(token):
        try:
            data = jwt.decode(token, 'secret', algorithms=['HS256'])
            return data['username'] == 'admin'
        except:
            return False

    @app.route('/example', methods=['GET'])
    @auth.login_required
    def example():
        return jsonify({'message': 'success'})

결론

이 글에서는 Python Flask를 이용하여 REST API 서버를 만드는 방법에 대해 알아보았습니다. Flask를 이용하면 간단하고 빠르게 REST API 서버를 만들 수 있습니다. 또한 Flask-RESTful을 이용하여 RESTful API를 쉽게 구현할 수 있습니다. 마지막으로 JWT 인증과 Flask-HTTPAuth를 이용하여 REST API 서버 보안을 강화할 수 있습니다.

자주 묻는 질문(FAQs)

  1. Python Flask를 이용한 REST API 서버는 무엇인가요?
    • Python Flask를 이용하여
  2. Flask에서 HTTP Method는 어떻게 처리되나요?
    • Flask에서는 HTTP Method에 따라 다르게 처리됩니다. 예를 들어, GET 메소드는 데이터 조회에 사용되고, POST 메소드는 데이터 생성에 사용됩니다.
  3. Flask-RESTful에서 Request Parsing을 어떻게 수행하나요?
    • Flask-RESTful에서는 reqparse 모듈을 이용하여 Request Parsing을 수행합니다. reqparse 모듈을 이용하면 요청한 데이터를 쉽게 받아올 수 있습니다.
  4. Flask-RESTful에서 Marshmallow를 이용하여 무엇을 할 수 있나요?
    • Flask-RESTful에서는 Marshmallow를 이용하여 데이터 검증 및 직렬화를 수행할 수 있습니다. Marshmallow를 이용하면 데이터의 유효성 검사를 쉽게 할 수 있습니다.
  5. JWT 인증은 무엇인가요?
    • JWT(Json Web Token) 인증은 REST API 서버에서 자주 사용되는 인증 방식 중 하나입니다. JWT는 서버에서 발행한 Token을 클라이언트가 저장하고, 이를 이용하여 인증을 수행합니다.

이상으로 Python Flask를 이용한 REST API 서버 만드는 방법에 대해 알아보았습니다. Flask를 이용하면 간단하고 빠르게 REST API 서버를 만들 수 있습니다. 또한 Flask-RESTful을 이용하여 RESTful API를 쉽게 구현할 수 있습니다. 마지막으로 JWT 인증과 Flask-HTTPAuth를 이용하여 REST API 서버 보안을 강화할 수 있습니다.

리스트 컴프리헨션과 for문은 모두 파이썬에서 반복문을 처리하는 방법 중 하나입니다. 그러나 두 가지 방법은 서로 다른 성능 특성을 가지고 있습니다.

일반적으로 리스트 컴프리헨션은 for문보다 더 빠른 실행 속도를 보입니다. 이는 리스트 컴프리헨션은 내부적으로 C 코드로 작성되어 있어 파이썬 인터프리터에서 해석되는 일반적인 for문에 비해 더 빠르기 때문입니다. 또한, 리스트 컴프리헨션은 코드가 더 짧고 간결하며 가독성이 높아 유지 보수가 더 쉽다는 이점도 있습니다.

그러나 리스트 컴프리헨션은 데이터 크기가 매우 큰 경우에는 메모리 사용량이 더 높을 수 있습니다. 리스트 컴프리헨션은 한 번에 모든 데이터를 생성하기 때문에 매우 큰 리스트를 생성하려면 많은 메모리가 필요합니다. 이에 비해 for문은 데이터를 한 번에 하나씩 처리하므로 메모리 사용량이 더 낮습니다.

따라서, 리스트 컴프리헨션과 for문 중 어느 것이 더 나은 방법인지는 상황에 따라 다릅니다. 작은 데이터 크기에서는 리스트 컴프리헨션이 더 나은 선택일 수 있으며, 대규모 데이터에서는 for문이 더 나은 선택일 수 있습니다.

리스트 컴프리헨션과 for문의 성능 비교를 위해 간단한 예제를 작성해보겠습니다. 예제는 1부터 100000까지의 숫자 리스트를 생성하고 각 숫자를 제곱하여 새로운 리스트를 생성하는 것입니다.

리스트 컴프리헨션을 사용한 예제:

import time

start_time = time.time()

num_list = [i**2 for i in range(1, 100001)]

end_time = time.time()
elapsed_time = end_time - start_time
print(f"Elapsed time using list comprehension: {elapsed_time:.5f} seconds")

결과:

Elapsed time using list comprehension: 0.02984 seconds

for문을 사용한 예제:

import time

start_time = time.time()

num_list = []
for i in range(1, 100001):
    num_list.append(i**2)

end_time = time.time()
elapsed_time = end_time - start_time
print(f"Elapsed time using for loop: {elapsed_time:.5f} seconds")

결과:

Elapsed time using for loop: 0.04094 seconds

위의 예제에서는 리스트 컴프리헨션과 for문을 사용하여 같은 작업을 수행합니다. 실행 시간을 측정하면 리스트 컴프리헨션이 약 0.03초, for문이 약 0.04초 걸렸다는 것을 알 수 있습니다. 이 예제에서는 리스트 컴프리헨션이 for문보다 더 빠른 것으로 나타났습니다.

객체지향 프로그래밍(Object-Oriented Programming)은 컴퓨터 프로그래밍 패러다임 중 하나로, 현실 세계를 객체(Object)라는 개념으로 모델링하여 프로그래밍 하는 방법입니다. Python은 객체지향 언어로, 클래스(Class)와 객체(Object)를 중심으로 프로그래밍이 이루어집니다.

클래스(Class)는 객체를 만들기 위한 설계도로, 객체를 만드는데 사용되는 변수와 함수들의 집합입니다. 예를 들어, 동물이라는 클래스를 만들 때, 동물의 특징인 눈, 다리, 꼬리 등의 변수와 움직이기, 먹기 등의 함수를 정의할 수 있습니다.

객체(Object)는 클래스를 기반으로 만들어진 실체입니다. 클래스를 인스턴스화(Instantiate) 하여 객체를 생성하고, 객체는 클래스에서 정의된 변수와 함수를 사용할 수 있습니다. 예를 들어, 동물 클래스를 인스턴스화하여 개, 고양이, 돼지 등의 객체를 생성하고, 이들 객체는 각각 눈, 다리, 꼬리 등의 변수와 움직이기, 먹기 등의 함수를 사용할 수 있습니다.

Python에서 클래스는 다음과 같이 정의됩니다.

class Animal:
    def __init__(self, eyes, legs, tail):
        self.eyes = eyes
        self.legs = legs
        self.tail = tail
        
    def move(self):
        print("I am moving")
        
    def eat(self, food):
        print("I am eating", food)

위의 코드는 Animal 클래스를 정의하는 예시입니다. 클래스는 class 예약어로 시작하며, 클래스 이름은 대문자로 시작하는 것이 관례입니다. __init__ 메서드는 객체가 생성될 때 자동으로 호출되는 생성자(Constructor)로, 클래스에서 정의된 변수들을 초기화합니다. **move**와 eat 메서드는 동물 객체에서 호출할 수 있는 함수입니다.

클래스에서 정의된 변수와 함수를 사용하기 위해서는, 객체를 먼저 생성해야 합니다.

dog = Animal(2, 4, True)
cat = Animal(2, 4, True)

dog.move() # "I am moving" 출력
cat.eat("fish") # "I am eating fish" 출력

위의 코드는 Animal 클래스에서 dog와 cat 객체를 생성한 후, move와 eat 함수를 호출하는 예시입니다. 이렇게 객체지향 프로그래밍에서는, 클래스를 설계하고, 객체를 생성하여 사용함으로써 현실 세계를 모델링하여 프로그래밍할 수 있습니다.

Docker는 컨테이너 간 통신을 위한 다양한 방법을 제공합니다. 이를 위해서는 컨테이너 간 네트워크를 설정해야 합니다.

  1. 사용자 정의 브리지 네트워크 생성 Docker에서는 사용자 정의 브리지 네트워크를 생성하여 두 개 이상의 컨테이너가 동일한 네트워크에서 통신할 수 있습니다. 먼저, 다음 명령어로 사용자 정의 브리지 네트워크를 생성합니다.
docker network create my-network

그리고 컨테이너를 실행할 때, --net 옵션을 사용하여 해당 네트워크에 연결합니다.

docker run --name container1 --net my-network image1
docker run --name container2 --net my-network image2

이제 container1에서 container2로 통신이 가능해집니다.

  1. 호스트 네트워크 사용 컨테이너가 호스트와 동일한 네트워크를 사용하도록 설정할 수 있습니다. 다음과 같이 --net=host 옵션을 사용하여 호스트 네트워크를 사용할 수 있습니다.
docker run --name container1 --net=host image1
docker run --name container2 --net=host image2

이제 container1에서 container2로 바로 통신이 가능합니다.

  1. 링크(Link) 사용 Docker는 --link 옵션을 사용하여 컨테이너 간 통신을 가능하게 합니다. 이 옵션을 사용하면, 명령어에서 컨테이너 이름을 지정할 수 있으며, 그에 따라 해당 컨테이너의 IP 주소 및 환경 변수를 사용할 수 있습니다.
docker run --name container1 --link container2:image2 image1

위의 예시에서 container1은 container2의 IP 주소 및 환경 변수를 사용할 수 있게 됩니다.

Docker는 위와 같은 방법을 통해 컨테이너 간 통신을 가능하게 합니다. 이를 통해 각각의 컨테이너는 독립적으로 실행되면서도 필요한 경우 다른 컨테이너와 연결하여 통신할 수 있습니다.

참고 문헌: [1] https://stackoverflow.com/questions/55862431/how-to-communicate-between-two-containers-using-docker[2] https://www.tutorialworks.com/container-networking/[3] https://stackoverflow.com/questions/30545023/how-to-communicate-between-docker-containers-via-hostname

'개발 > Docker' 카테고리의 다른 글

도커 기본 명령어 설명 (Docker basic commands)  (0) 2023.03.09

컨테이너 기반 가상화 기술인 Docker에서 가장 많이 사용되는 50가지 기본 명령어에 대해 설명하고, 예시를 보여드리겠습니다.

  1. docker run - 컨테이너를 생성하고 실행합니다. 예시: docker run -it ubuntu /bin/bash
  2. docker ps - 실행 중인 컨테이너 목록을 확인합니다. 예시: docker ps
  3. docker stop - 실행 중인 컨테이너를 정지합니다. 예시: docker stop <컨테이너 ID>
  4. docker images - 로컬 이미지 목록을 확인합니다. 예시: docker images
  5. docker rmi - 로컬 이미지를 삭제합니다. 예시: docker rmi <이미지 ID>
  6. docker build - Dockerfile을 사용하여 이미지를 빌드합니다. 예시: docker build -t my-image:latest .
  7. docker logs - 컨테이너 로그를 확인합니다. 예시: docker logs <컨테이너 ID>
  8. docker inspect - 컨테이너 또는 이미지에 대한 세부 정보를 확인합니다. 예시: docker inspect <컨테이너 또는 이미지 ID>
  9. docker exec - 실행 중인 컨테이너에서 명령을 실행합니다. 예시: docker exec -it <컨테이너 ID> /bin/bash
  10. docker push - 이미지를 Docker Hub 또는 다른 Docker 레지스트리에 푸시합니다. 예시: docker push my-image:latest
  11. docker pull - Docker Hub 또는 다른 Docker 레지스트리에서 이미지를 가져옵니다. 예시: docker pull ubuntu:latest
  12. docker network create - Docker 네트워크를 생성합니다. 예시: docker network create my-network
  13. docker network ls - Docker 네트워크 목록을 확인합니다. 예시: docker network ls
  14. docker network connect - 컨테이너를 Docker 네트워크에 연결합니다. 예시: docker network connect my-network <컨테이너 ID>
  15. docker network disconnect - 컨테이너를 Docker 네트워크에서 분리합니다. 예시: docker network disconnect my-network <컨테이너 ID>
  16. docker port - 컨테이너의 포트 매핑 정보를 확인합니다. 예시: docker port <컨테이너 ID>
  17. docker rename - 컨테이너의 이름을 변경합니다. 예시: docker rename old-name new-name
  18. docker rm - 컨테이너를 삭제합니다. 예시: docker rm <컨테이너 ID>
  19. docker attach - 실행 중인 컨테이너에 접속합니다. 예시: docker attach <컨테이너 ID>
  20. docker cp - 컨테이너와 호스트 간에 파일
  21. docker cp - 컨테이너와 호스트 간에 파일을 복사합니다. 예시: docker cp <컨테이너 ID>:<컨테이너 내부 경로> <호스트 경로>
  22. docker commit - 컨테이너에서 새로운 이미지를 생성합니다. 예시: docker commit <컨테이너 ID> my-image:latest
  23. docker save - 이미지를 tar 파일로 저장합니다. 예시: docker save my-image:latest > my-image.tar
  24. docker load - tar 파일에서 이미지를 로드합니다. 예시: docker load < my-image.tar
  25. docker history - 이미지의 빌드 기록을 확인합니다. 예시: docker history my-image:latest
  26. docker tag - 이미지에 새로운 태그를 추가합니다. 예시: docker tag my-image:latest my-image:newtag
  27. docker search - Docker Hub에서 이미지를 검색합니다. 예시: docker search mysql
  28. docker stats - 실행 중인 컨테이너의 리소스 사용량을 확인합니다. 예시: docker stats <컨테이너 ID>
  29. docker top - 실행 중인 컨테이너에서 실행 중인 프로세스를 확인합니다. 예시: docker top <컨테이너 ID>
  30. docker wait - 컨테이너가 종료될 때까지 대기합니다. 예시: docker wait <컨테이너 ID>
  31. docker events - Docker 이벤트를 모니터링합니다. 예시: docker events
  32. docker pause - 실행 중인 컨테이너를 일시 중지합니다. 예시: docker pause <컨테이너 ID>
  33. docker unpause - 일시 중지된 컨테이너를 다시 시작합니다. 예시: docker unpause <컨테이너 ID>
  34. docker update - 실행 중인 컨테이너의 설정을 업데이트합니다. 예시: docker update --cpus 2 <컨테이너 ID>
  35. docker diff - 컨테이너에서 파일 시스템의 변경 사항을 확인합니다. 예시: docker diff <컨테이너 ID>
  36. docker export - 컨테이너를 tar 파일로 내보냅니다. 예시: docker export <컨테이너 ID> > my-container.tar
  37. docker import - tar 파일에서 컨테이너를 생성합니다. 예시: docker import my-container.tar my-image:latest
  38. docker system df - Docker 시스템의 디스크 사용량을 확인합니다. 예시: docker system df
  39. docker system prune - 사용하지 않는 컨테이너, 이미지 등을 삭제합니다. 예시: docker system prune
  40. docker version - Docker 버전 정보를 확인합니다. 예시: docker version
  41. docker info - Docker 시스템 정보를 확인합니다. 예시: docker info
  42. docker login
  43. docker login - Docker Hub 또는 다른 Docker 레지스트리에 로그인합니다. 예시: docker login
  44. docker logout - Docker Hub 또는 다른 Docker 레지스트리에서 로그아웃합니다. 예시: docker logout
  45. docker system events - Docker 시스템 이벤트를 모니터링합니다. 예시: docker system events
  46. docker system info - Docker 시스템 정보를 상세하게 확인합니다. 예시: docker system info
  47. docker system prune - 사용하지 않는 리소스를 삭제합니다. 예시: docker system prune
  48. docker system events --since '2022-01-01' - 특정 날짜 이후의 Docker 이벤트를 모니터링합니다. 예시: docker system events --since '2022-01-01'
  49. docker system events --filter 'event=start' - 특정 이벤트만 모니터링합니다. 예시: docker system events --filter 'event=start'
  50. docker inspect -f '{{.NetworkSettings.IPAddress}}' <컨테이너 ID> - 컨테이너의 IP 주소를 확인합니다. 예시: docker inspect -f '{{.NetworkSettings.IPAddress}}' my-container
  51. docker run -p 80:80 nginx - 호스트의 포트와 컨테이너의 포트를 매핑합니다. 예시: docker run -p 8080:80 nginx
  52. docker run -v /host/path:/container/path - 호스트 경로와 컨테이너 경로를 연결합니다. 예시: docker run -v /data:/app/data my-image:latest
  53. docker run -e <환경 변수> - 컨테이너에서 사용할 환경 변수를 설정합니다. 예시: docker run -e MYSQL_ROOT_PASSWORD=pass1234 mysql:latest
  54. docker run -d - 컨테이너를 백그라운드 모드로 실행합니다. 예시: docker run -d my-image:latest
  55. docker-compose up - Docker Compose를 사용하여 여러 컨테이너를 실행합니다. 예시: docker-compose up
  56. docker-compose down - Docker Compose로 실행한 컨테이너를 정지합니다. 예시: docker-compose down
  57. docker-compose build - Docker Compose에서 정의된 서비스를 빌드합니다. 예시: docker-compose build
  58. docker-compose logs - Docker Compose로 실행한 서비스의 로그를 확인합니다. 예시: docker-compose logs
  59. docker-compose ps - Docker Compose로 실행한 서비스 목록을 확인합니다. 예시: docker-compose ps
  60. docker-compose run - Docker Compose에서 서비스를 실행합니다. 예시: docker-compose run my-service /bin/bash
  61. docker-compose restart - Docker Compose에서 서비스를 재시작합니다. 예시: docker-compose restart my-service
  62. docker-compose stop - Docker Compose에서 서비스를 정지합니다. 예시: docker-compose stop my-service
  63. docker-compose pull - Docker Compose에서 정의된 서비스의 이미지를 가져옵니다. 예시: docker-compose pull
  64. docker-compose exec - Docker Compose에서 실행 중인 서비스에서 명령을 실행합니다. 예시: docker-compose exec my-service /bin/bash
  65. docker-compose up -d - Docker Compose로 여러 서비스를 백그라운드 모드로 실행합니다. 예시: docker-compose up -d
  66. docker-compose down -v - Docker Compose로 실행한 컨테이너와 볼륨을 모두 삭제합니다. 예시: docker-compose down -v
  67. docker swarm init - Docker Swarm 모드를 초기화합니다. 예시: docker swarm init
  68. docker swarm join - 다른 노드를 Docker Swarm 클러스터에 추가합니다. 예시: docker swarm join --token <토큰> <매니저 노드 주소>
  69. docker service create - Docker Swarm 모드에서 서비스를 생성합니다. 예시: docker service create --name my-service my-image:latest
  70. docker service scale - Docker Swarm 모드에서 서비스의 인스턴스 수를 조정합니다. 예시: docker service scale my-service=5
  71. docker service ls - Docker Swarm 모드에서 실행 중인 서비스 목록을 확인합니다. 예시: docker service ls
  72. docker service logs - Docker Swarm 모드에서 실행 중인 서비스의 로그를 확인합니다. 예시: docker service logs my-service
  73. docker service ps - Docker Swarm 모드에서 실행 중인 서비스의 태스크 목록을 확인합니다. 예시: docker service ps my-service
  74. docker service update - Docker Swarm 모드에서 서비스의 설정을 업데이트합니다. 예시: docker service update --image my-image:latest my-service
  75. docker stack deploy - Docker Swarm 모드에서 스택을 배포합니다. 예시: docker stack deploy --compose-file docker-compose.yml my-stack
  76. docker stack rm - Docker Swarm 모드에서 스택을 제거합니다. 예시: docker stack rm my-stack
  77. docker node ls - Docker Swarm 클러스터에 속한 노드 목록을 확인합니다. 예시: docker node ls
  78. docker node inspect - Docker Swarm 클러스터의 노드에 대한 정보를 확인합니다. 예시: docker node inspect <노드 ID>
  79. docker node update - Docker Swarm 클러스터의 노드 설정을 업데이트합니다. 예시: docker node update --availability drain <노드 ID>
  80. docker stack services - Docker Swarm 모드에서 스택에 속한 서비스 목록을 확인합니다. 예시: docker stack services my-stack
  81. docker stack ps - Docker Swarm 모드에서 스택에 속한 태스크 목록을 확인합니다. 예시: docker stack ps my-stack
  82. docker secret create - Docker Swarm 모드에서 시크릿을 생성합니다. 예시: echo "mysecret" | docker secret create my-secret -
  83. docker secret ls - Docker Swarm 모드에서 시크릿 목록을 확인합니다. 예시: docker secret ls
  84. docker secret inspect - Docker Swarm 모드에서 시크릿에 대한 정보를 확인합니다. 예시: docker secret inspect my-secret
  85. docker secret rm - Docker Swarm 모드에서 시크릿을 삭제합니다. 예시: docker secret rm my-secret
  86. docker config create - Docker Swarm 모드에서 설정을 생성합니다. 예시: echo "myconfig" | docker config create my-config -
  87. docker config ls - Docker Swarm 모드에서 설정 목록을 확인합니다. 예시: docker config ls
  88. docker config inspect - Docker Swarm 모드에서 설정에 대한 정보를 확인합니다. 예시: docker config inspect my-config
  89. docker config rm - Docker Swarm 모드에서 설정을 삭제합니다. 예시: docker config rm my-config
  90. docker swarm leave - Docker Swarm 클러스터에서 노드를 제거합니다. 예시: docker swarm leave --force
  91. docker swarm update - Docker Swarm 클러스터의 설정을 업데이트합니다. 예시: docker swarm update --cert-expiry 72h
  92. docker plugin install - Docker 플러그인을 설치합니다. 예시: docker plugin install my-plugin
  93. docker plugin ls - Docker 플러그인 목록을 확인합니다. 예시: docker plugin ls
  94. docker plugin rm - Docker 플러그인을 삭제합니다. 예시: docker plugin rm my-plugin
  95. docker system prune -a - 사용하지 않는 모든 리소스를 삭제합니다. 예시: docker system prune -a
  96. docker system events --filter 'type=container' - 실행 중인 컨테이너 이벤트만 모니터링합니다. 예시: docker system events --filter 'type=container'
  97. docker stats <컨테이너 ID> --no-stream - 컨테이너의 리소스 사용량을 한 번만 확인합니다. 예시: docker stats my-container --no-stream

'개발 > Docker' 카테고리의 다른 글

Docker 컨테이너 통신  (0) 2023.03.09

1. 리스트 순회하기

fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    print(fruit)

결과:

apple
banana
cherry

2. 리스트 요소와 함께 인덱스 출력하기

fruits = ['apple', 'banana', 'cherry']

for index, fruit in enumerate(fruits):
    print(index, fruit)

결과:

0 apple
1 banana
2 cherry

3. 구구단 출력하기

for i in range(2, 10):
    for j in range(1, 10):
        print(f"{i} x {j} = {i*j}")
    print()

결과:

2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18

3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27

...

9 x 1 = 9
9 x 2 = 18
9 x 3 = 27
9 x 4 = 36
9 x 5 = 45
9 x 6 = 54
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81

4. 별찍기

for i in range(1, 6):
    for j in range(i):
        print('*', end='')
    print()

결과:

*
**
***
****
*****

5. 문자열 거꾸로 출력하기

string = "hello world"

for char in reversed(string):
    print(char, end='')

결과:

dlrow olleh

6. 딕셔너리 순회하기

fruits = {'apple': 1, 'banana': 2, 'cherry': 3}

for key, value in fruits.items():
    print(key, value)

결과:

apple 1
banana 2
cherry 3

7. 파일의 각 라인 출력하기

with open('filename.txt', 'r') as f:
    for line in f:
        print(line)

8. 1부터 100까지의 합 구하기

sum = 0

for i in range(1, 101):
    sum += i

print(sum)

결과:

5050

 

이상입니다. 파이썬 for문의 다양한 예제를 알려드렸습니다. 어려운 예제도 있지만, 차근차근 따라해보시면 누구나 쉽게 익힐 수 있을 것입니다

@@trancount : 트랜잭션의 중첩 수준을 나타내는 시스템 함수. Begin tran 문에 의해 1씩 증가하고 commit tran 에 의해 1씩 감소한다. rollback tran 을 만나면 모두 롤백하면서 어떤 값을 가지고 있더라도 0 으로 변한다.

sp를 작성할 때 데이터의 정합성을 보장하기 위해서 트랜잭션을 사용하게 됩니다. 트랜잭션을 시작하면 언제나 begin tran, commit tran의 짝이 일치해야 하는 것은 당연하지요. 즉, 트랜잭션이 중첩되어서 begin tran 을 세번하게 되면 세번 commit 이 있어야 합니다. 단 rollback 은 한번에 @@trancount 를 0 으로 만들고 rollback 하기 때문에 rollback 하기 전에 언제나 @@trancount 를 체크하면서 rollback 해야 합니다.

begin tran

INSERT INTO DEPT ( … )

if @@error <> 0 or @@rowcount <> 1 
begin 
  if @@trancount > 0 rollback 
  select -1 as err_code 
  return
end

INSERT INTO TEST_TBL ( … )

if @@error <> 0 or @@rowcount <> 1
begin
  if @@trancount > 0 rollback
  select -2 as err_code
  return
end

if @@trancount > 0 commit

rollback 이나 commit 하기 전에 @@trancount 를 체크하는 것은 sp들간에 복잡하게 호출하고 각 sp들이 자체적으로 transaction 을 사용할 때 위력을 발휘합니다. 중첩 트랜잭션 처리에 관한 사항은 기배포한 중첩 트랜잭션 처리 가이드를 참고해주세요.


출처:http://itouch.tistory.com/17

'개발 > DB' 카테고리의 다른 글

WITH절과 CTE (비재귀적)  (0) 2015.05.21
MSSQL 컬럼추가, 수정, 삭제  (0) 2015.05.14
mssql 2012 추가 및 변경점  (0) 2015.03.20
N 따옴표 [N']  (0) 2015.03.09
IF 조건문 EXISTS 사용 예 (값 유무 체크)  (0) 2015.03.05
1. WITH CTE

WITH 절은 CTE(Common Table Expression)
공통 테이블 식을 표현하기 위한 구문이며, SQLServer 2005부터 등장하였다.

MSDN의 CTE 페이지를 참고하자.

CTE는 SELECT, INSERT, UPDATE, DELETE 또는 CREATE VIEW 문 
하나의 실행 범위 내에서 정의되는 임시 결과 집합이라고 볼 수 있다.

CTE는 개체로 저장되지 않고 쿼리 지속 시간 동안만 존재한다는 점에서 파생 테이블과 비슷하나, 
CTE는 파생 테이블과 달리 자체 참조가 가능하며 동일 쿼리에서 여러 번 참조될 수 있다.

CTE를 사용하여 다음과 같은 것들을 수행할 수 있다.
  • 재귀 쿼리를 만들 수 있다 (다음 챕터에서...)
  • 일반적인 뷰 사용이 필요하지 않을 때, 즉 메타데이터에 정의를 저장할 필요가 없을 때 뷰를 대체할 수 있다
  • 스칼라 하위 SELECT에서 파생된 열 또는 비결정적이거나 외부 액세스가 없는 함수를 기준으로 그룹화할 수 있다
  • 동일 문에서 결과 테이블을 여러 번 참조할 수 있다
CTE를 사용하면 가독성이 향상되고 복잡한 쿼리를 쉽게 유지 관리할 수 있는 이점이 있다. 

쿼리를 개별적이고 단순한 논리적 구성 블록으로 나눈 뒤에,
이 단순한 블록을 사용하여 최종 결과 집합이 생성될 때까지 보다 복잡한 중간 CTE를 작성할 수 있다.

CTE는 함수, 저장 프로시저, 트리거 또는 뷰 같은 사용자 정의 루틴에서 정의될 수 있다.

결론적으로, CTE는 기존의 뷰, 파생 테이블, 임시 테이블 등으로 
사용되던 것을 대신할 수 있으며, 더 간결한 식으로 보이는 장점이 있다.

CTE는 비재귀적 CTE와 재귀적 CTE로 나뉘어지는데, 이번 챕터에서는 비재귀적 CTE에 대해서만 다루겠다.


2. CTE 구문

CTE는 CTE를 나타내는 식 이름, 선택적인 열 목록 및 CTE를 정의하는 쿼리로 구성되어 있다. 

CTE를 정의한 후에는 SELECT, INSERT, UPDATE 또는 DELETE 문에서 테이블이나 뷰처럼 참조할 수 있다. 
CTE는 CREATE VIEW 문에서 정의하는 SELECT 문의 일부분으로도 사용될 수 있다.

CTE의 기본 구문 구조는 다음과 같다.

  1. -- expression_name의 CTE를 생성한다.
  2. WITH expression_name [ ( column_name [,...n] ) ]
  3. AS
  4. (
  5.     CTE_query_definition
  6. )
  7.  
  8. -- 이후 expression_name을 마치 테이블명처럼 사용할 수 있다.
  9. SELECT <column_list> FROM expression_name

(SELECT 외에 UPDATE 등도 가능하지만, 주요 사용되는 용도는 SELECT와 부합된다)

기존에는 SELECT <column-name...> FROM 실제DB테이블을 사용하였지만,
CTE는 바로 위의 WITH 절에서 정의한 expression_name 테이블명을 사용하는 것만 다르다.

즉, 'WITH expression_name AS...' 형식의 테이블이 하나 더 있다고 생각하면 쉽다.


3. 예제

이해를 돕기 위해서는 예제가 최고이니...
앞서 사용하였던 BuyTable에서 총구매액을 다시 구해보도록 하자.

  1. SELECT ID, SUM(Amount * Price) AS TotalCost FROM BuyTable
  2. GROUP BY ID

위 결과를 총구매액이 많은 사용자 순서로 정렬할 때, GROUP BY에 이어 ORDER BY를 첨가해도 된다.

하지만, 위 쿼리의 결과가 바로 UserTotalCost라는 테이블이라고 생각하면 어떨까?
그렇다면, 정렬하는 쿼리는 아래와 같이 간단해 진다.

SELECT * FROM UserTotalCost ORDER BY TotalCost DESC

이것이 바로 위에서 얘기했던 CTE의 장점 중 하나인 구문 단순화이다.

지금까지의 내용을 모두 쿼리로 작성하면 아래와 같다.

  1. -- WITH절이 시작되기 전 마지막 구문은 세미콜론(;)으로 끝나야 한다
  2. -- 또는 GO 구문을 사용해 주어야 한다.
  3. -- USE Son
  4. -- GO
  5. USE Son;
  6.  
  7. -- UserTotalCost라는 이름의 CTE
  8. WITH UserTotalCost(ID, TotalCost)
  9. AS
  10. (
  11.     SELECT ID, SUM(Amount * Price) AS TotalCost FROM BuyTable
  12.     GROUP BY ID
  13. )
  14.  
  15. -- 마치 실제 테이블처럼 사용이 가능하다
  16. SELECT * FROM UserTotalCost ORDER BY TotalCost DESC



마지막 SELECT * FROM의 UserTotalCost는 실존하는 테이블이 아니라, 
바로 위에서 WITH 구문으로 만든 SELECT의 결과이다.

여기에서 CTE의 AS (...)내의 칼럼 수와 WITH UserTotalCost(...)의 칼럼 수는 동일해야 한다.

이 UserTotalCost는 이 쿼리문이 완전히 종료되면 소멸하게 된다.

그리고, 위 예제에서 보듯이 WITH 절 앞 구문은 반드시 'GO' 또는 세미콜론(;)으로 끝나야 한다.
그렇지 않으면, 아래와 같이 에러가 발생한다.

메시지 319, 수준 15, 상태 1, 줄 3
키워드 'with' 근처의 구문이 잘못되었습니다. 
이 문이 공통 테이블 식이거나, xmlnamespaces 절이거나, 변경 내용 추적 컨텍스트 절인 경우에는 
이전 문을 세미콜론으로 종료해야 합니다.


4. CTE의 매력

지금까지의 예제만 본다면 사실 CTE를 굳이 써야 하나 싶지만, 
아래와 같은 시나리오를 생각해 본다면, 많은 부분의 단순화 -> 명확한 쿼리문 작성이 가능하게 된다.

"각 지역별로 가장 큰 키의 평균값을 구하라"

위와 같은 목표를 달성하려면, 우선 쿼리를 세분화된 단계로 생각해 볼 필요가 있다.
  1. 각 지역별로 가장 큰 키를 쿼리한다.
  2. 이들의 평균값을 계산한다.
가장 큰 값을 구하는 것도 집계함수(MAX)이고, 이들의 평균을 구하는 것도 집계함수(AVG)이다.
하위쿼리를 쓴다해도 이를 하나의 SELECT 구문으로는 처리할 수 없다.

이럴 때 다음과 같이 CTE를 활용하는 것이다.

1. 각 지역별로 가장 큰 키를 쿼리한다.

  1. SELECT Addr, MAX(Height) FROM UserTable
  2. GROUP BY Addr

2. 이 쿼리를 WITH 구문으로 묶는다.

  1. WITH AddrMaxHeight(Addr, MaxHeight)
  2. AS
  3. (
  4.     SELECT Addr, MAX(Height) AS MaxHeight FROM UserTable
  5.     GROUP BY Addr
  6. )

3. 키의 평균을 구하는 쿼리를 작성한다.

  1. USE Son
  2. GO
  3.  
  4. WITH AddrMaxHeight(Addr, MaxHeight)
  5. AS
  6. (
  7.     SELECT Addr, MAX(Height) AS MaxHeight FROM UserTable
  8.     GROUP BY Addr
  9. )
  10.  
  11. SELECT AVG(MaxHeight * 1.0) AS [각 지역별 최고 키들의 평균] FROM AddrMaxHeight

복잡한 단계의 쿼리를 작성해야 할 경우에 이러한 단계로 분할해서 생각하면,
이전보다 쉽게 SQL문을 작성할 수 있을 것이다.


5. 중복 CTE

CTE는 다음과 같은 형식의 중복 CTE를 지원한다.

  1. WITH
  2. AAA(columns...)
  3. AS (query of AAA),
  4. BBB(columns...)
  5. AS (query of BBB),
  6. CCC(columns...)
  7. AS (query of CCC)
  8.  
  9. SELECT * FROM [AAA or BBB or CCC]

위와 같이 사용시 주의할 점이, CCC의 AS 쿼리문에서는 AAA, BBB를 참조할 수 있지만, 그 반대의 참조는 불가능하다.
즉, 아직 정의되지 않은 CTE를 미리 참조할 수 없다는 의미이다.


출처 http://egloos.zum.com/sweeper/v/3000836


'개발 > DB' 카테고리의 다른 글

@@trancount  (0) 2015.06.15
MSSQL 컬럼추가, 수정, 삭제  (0) 2015.05.14
mssql 2012 추가 및 변경점  (0) 2015.03.20
N 따옴표 [N']  (0) 2015.03.09
IF 조건문 EXISTS 사용 예 (값 유무 체크)  (0) 2015.03.05

추가

alter table [테이블명] add [필드명] [속성]

 

alter table table_name add field_name varchar(32) null

alter table table_name add field_name varchar(32) not null contraint default_value 'N'

 

 

수정

alter table [테이블명] alter column [컬럼명] [속성]

alter table table_name alter column varchar(32) null


 

컬럼명 수정

exec sp_rename '[테이블명].[수정할컬럼명]', '[수정될 이름]', 'column'

sp_rename 'table_name.field_name', 'field_name2', 'column'


 

컬럼삭제

alter table [테이블명] dorp column [컬럼명]

alter table table_name drop column field_name

'개발 > DB' 카테고리의 다른 글

@@trancount  (0) 2015.06.15
WITH절과 CTE (비재귀적)  (0) 2015.05.21
mssql 2012 추가 및 변경점  (0) 2015.03.20
N 따옴표 [N']  (0) 2015.03.09
IF 조건문 EXISTS 사용 예 (값 유무 체크)  (0) 2015.03.05

sequence
-------------------------->

CREATE TABLE Sequence_Test
(
    Seq INT, Val VARCHAR(5)
)
GO

CREATE SEQUENCE SeqTest
START WITH 1
INCREMENT BY 1 ;
GO

INSERT INTO Sequence_Test(Seq, Val)
VALUES (NEXT VALUE FOR SeqTest, 'test')
GO 3

 

SELECT * FROM Sequence_Test
GO

//결과값
Seq Val
1 test
2 test
3 test

<--------------------------

 

OFFSET / FETCH
------------------------>

ORDER BY IDX DESC
OFFSET (@PAGE - 1) * @PAGESIZE ROWS
FETCH NEXT @PAGESIZE ROWS ONLY

<------------------------

 

THROW
--------------------------------->

BEGIN TRY

             INSERT [HumanResources].[Department] (Name, GroupName)

             VALUES ('Engineering','Manufacturing')

END TRY

BEGIN CATCH

              THROW 50001,'부서 이름 중복',1;

 

END CATCH

 

--(0 행이 영향을 받음)

--메시지 50001, 수준 16, 상태 1, 7

--부서 이름 중복

 

매개변수 없이 지정 된 THROW CATCH 블럭 내 정의

 - THROW 문이 발생하면 일괄 처리 종료
 - THROW 가 발생할 경우 심각도 16 발생
 - THROW 을 정의할 경우 세미콜론(;) 종결자 필요

<--------------------------

 

 

EXECUTE WITH RESULT SETS

--------------------------->

image_8.png

 <------------------------------------------

 

EOMONTH

-------------------------------------->

DECLARE @DT1 VARCHAR(10);

DECLARE @DT2 DATETIME;

 

SET @DT1 = '2012-02-20';

SET @DT2 = CONVERT(DATETIME, @DT1);

 

SELECT

        EOMONTH(@DT1) AS 'EOMONTH(@DT1)',

        EOMONTH(@DT2) AS 'EOMONTH(@DT2)',

        EOMONTH(@DT1,2) AS 'EOMONTH(@DT1,2)',

        EOMONTH(@DT2,2) AS 'EOMONTH(@DT2,2)'

 

 

2.png 

<---------------------------------------------

 

DATEFROMPARTS 

--------------------------------------->

DATEFROMPARTS ( year, month, day )

예제
SELECT DATEFROMPARTS ( 2010, 12, 31 ) AS Result;

결과값  : 2010-12-31

<---------------------------------------

'개발 > DB' 카테고리의 다른 글

WITH절과 CTE (비재귀적)  (0) 2015.05.21
MSSQL 컬럼추가, 수정, 삭제  (0) 2015.05.14
N 따옴표 [N']  (0) 2015.03.09
IF 조건문 EXISTS 사용 예 (값 유무 체크)  (0) 2015.03.05
MS-SQL 문법정리  (0) 2015.03.05

+ Recent posts