이전 포스팅인 Flask를 설치하고 간단한 API만들기에서는 Flask를 설치하고 간단한 서버를 띄우는 작업을 했습니다. 전에 만들었던 회원가입 API에서 불편한 점은 API가 새로 재시작될 때 마다 모든 데이터가 없어진다는 것 입니다. 데이터를 저장하기 위해서는 데이터베이스 시스템을 사용해야합니다. 이번에는 1장에서 만들었던 간단한 회원가입 API에 MySQL 데이터 베이스 시스템과 연결시켜서 데이터들이 보존하려고 합니다.
1. MySQL 설치
Homebrew로 MySQL 데이터 베이스를 간단하게 설치할 수 있습니다.
brew install mysql
mysql_secure_installation 명령어를 실행해서 root 사용자의 비밀번호를 설정해줍니다.
mysql_secure_installation
brew를 통해 MySQL을 설치하면 아래와 같은 에러가 발생할 수 있습니다.
Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
이 경우 아래의 명령어로 재설치해줍니다.
# Homwbrew로 mysql을 설치한 경우 아래의 명령어로 해결 가능
brew services restart mysql
# 다시 비밀번호와 기본 옵션 설정
mysql_secure_installation
MySQL을 실행해줍니다.
mysql.server start
아래와 같은 메세지가 뜨면 성공한 것 입니다 !
"Starting MySQL SUCCESS!"
MySQL 데이터베이스의 현재 실행 여부 상태를 보고 싶으면 다음 명령어를 실행하면 됩니다.
mysql.server status
만약 MySQL 을 실행 정지하고 싶으면 다음 명령어를 실행해줍니다.
mysql.server stop
MySQL에 접속해봅시다.
- -u: MySQL에 접속할 사용자의 아이디를 명시합니다. (root 사용자로 접속합니다.
- -p: 비밀번호를 직접입력합니다.
mysql -u root -p
데이터 베이스를 생성합니다. test라는 이름의 데이터 베이스를 만들어보겠습니다.
CREATE DATABASE FLASK_BASIC;
데이터 베이스가 잘 생성되었는지 데이터 베이스 목록을 조회해봅시다.
SHOW DATABASES;
데이터베이스를 생성했으면 해당 데이터베이스를 사용한다는 것을 명시해줘야 합니다. use 명령어를 통해서 MySQL 데이터베이스 시스템에 알려줄 수 있습니다.
USE FLASK_BASIC;
이번에는 데이터 베이스를 생성하고 사용을 명시줬으니, 이번에는 테이블을 만들어봅시다. 회원가입과 관련된 정보를 저장할 테이블이기 때문에 아래와 같은 형태로 테이블 스키마를 설정해줍니다.
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT, # AUTO_INCREMENT: 해당 칼럼의 값이 자동으로 1씩 증가된다.
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
profile VARCHAR(1000) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id), # 고유키로 설정할 컬럼
UNIQUE KEY email (email) # 해당 컬럼의 값이 중복되는 값이 존재하면 안됨
);
테이블이 잘 만들어졌는지 확인해봅시다. 아마 users 테이블이 만들어진 것을 확인할 수 있습니다.
SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| users |
+----------------+
이번에는 users 테이블을 명시해서 확인해봅시다.
explain users;
위에서 정한 스카마데로 테이블이 만들어진 것을 확인할 수 있습니다.
+------------+--------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-------------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+--------------+------+-----+-------------------+-------------------+
만약 테이블을 삭제하고 싶으면 아래의 명령어를 실행하면 됩니다.
drop table users;
2. MySQL을 Flask와 연동하기
데이터 베이스와 테이블을 성공적으로 만들었으니 이제는 Flask와 연동해봅시다. API에 MySQL을 연동하려면 SQLAlchemy라는 라이브러리를 설치해야 합니다. 이 라이브러리는 파이썬 코드로 데이터 베이스에 연결할 수 있도록 돕는 라이브러리 입니다.
pip install sqlalchemy
SQLAlchemy 에서 MySQL을 사용하기 위해서는 MySQL용 DBAPI 또한 설치해야합니다. DBAPI는 이름 그대로 DB를 사용하기 위한 API인데요. MySQL의 공식 파이썬 DBAPI인 MySQL -Connector를 사용해보겠습니다.
pip install mysql-connector-python
다음으로는 데이터베이스 연결 정보를 만들어봅시다. config.py 라는 이름으로 새로운 파일을 만들어줍니다.
db = {
# 데이터베이스에 접속할 사용자 아이디
'user': 'root',
# 사용자 비밀번호
'password': 'test1234',
# 접속할 데이터베이스의 주소 (같은 컴퓨터에 있는 데이터베이스에 접속하기 때문에 localhost)
'host': 'localhost',
# 관계형 데이터베이스는 주로 3306 포트를 통해 연결됨
'port': 3306,
# 실제 사용할 데이터베이스 이름
'database': 'test'
}
DB_URL = f"mysql+mysqlconnector://{db['user']}:{db['password']}@{db['host']}:{db['port']}/{db['database']}?charset=utf8"
이제 데이터 베이스 연결 정보도 만들어줬으니 HTTP 요청을 통해 전달받은 회원의 정보를 데이터 베이스에 저장하는 코드를 작성해봅시다. 편의를 위해 sign-up.py 라는 새로운 파일을 만들고 아래의 코드를 작성해줍니다.
from flask import Flask, request, jsonify, current_app
from flask.json import JSONEncoder
from sqlalchemy import create_engine, text
def get_user(user_id):
user = current_app.database.execute(text("""
SELECT
id,
name,
email,
profile
FROM users
WHERE id = :user_id
"""), {
'user_id' : user_id
}).fetchone()
return {
'id' : user['id'],
'name' : user['name'],
'email' : user['email'],
'profile' : user['profile']
} if user else None
# HTTP 요청을 통해 전달받은 회원가입 정보를 데이터 베이스에 저장함
def insert_user(user):
return current_app.database.execute(text("""
INSERT INTO users (
name,
email,
profile,
hashed_password
) VALUES (
:name,
:email,
:profile,
:password
)
"""), user).lastrowid # 새로 사용자가 생성되면 새로 생성된 사용자의 아이디를 읽어들인다.
def create_app(test_config = None):
app = Flask(__name__)
# unit-test를 실행할 때 테스트 데이터 베이스에 대한 정보를 넣어준다.
if test_config is None:
app.config.from_pyfile("config.py")
else:
app.config.update(test_config)
# 데이터 베이스와 연동해준다.
database = create_engine(app.config['DB_URL'], encoding = 'utf-8', max_overflow = 0)
app.database = database
@app.route("/sign-up", methods=['POST'])
def sign_up():
new_user = request.json
new_user_id = insert_user(new_user)
new_user = get_user(new_user_id)
return jsonify(new_user)
return app
이제 서버를 다시 띄워봅시다.
FLASK_APP=sign_up.py FLASK_DEBUG=1 flask run
이제 서버에 요청을 보내봅시다.
http -v POST http://127.0.0.1:5000/sign-up name=크리스토프 email=rhswl2135@gmail.com password=tada1234 profile="타다 데이터팀의 크리스토프 입니다. 반갑습니다."
다음과 같은 결과를 확인할 수 있습니다.
POST /sign-up HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 239
Content-Type: application/json
Host: 127.0.0.1:5000
User-Agent: HTTPie/2.4.0
{
"email": "rhswl2135@gmail.com",
"name": "크리스토프",
"password": "tada1234",
"profile": "타다 데이터팀의 크리스토프 입니다. 반갑습니다."
}
HTTP/1.0 200 OK
Content-Length: 238
Content-Type: application/json
Date: Wed, 05 May 2021 08:32:07 GMT
Server: Werkzeug/1.0.1 Python/3.7.10
{
"email": "rhswl2135@gmail.com",
"id": 1,
"name": "크리스토프",
"profile": "타다 데이터팀의 크리스토프 입니다. 반갑습니다."
}
이제 데이터가 잘 적재되었는지 확인해봅시다. mysql에 접속한 후 아래의 명령어로 테이블을 확인해봅시다.
SELECT * FROM users;
아래와 같은 결과를 확인할 수 있고, 데이터가 잘 적재된 것을 확인할 수 있습니다. 이제 서버를 종료하더라도 데이터 유실 없이 과거 데이터를 조회할 수 있습니다.
+----+-----------------+---------------------+----------+--------------------------------------------------------------------+---------------------+
| id | name | email | password | profile | created_at |
+----+-----------------+---------------------+----------+--------------------------------------------------------------------+---------------------+
| 1 | 크리스토프 | rhswl2135@gmail.com | tada1234 | 타다 데이터팀의 크리스토프 입니다. 반갑습니다. | 2021-05-05 17:32:07 |
+----+-----------------+---------------------+----------+-----------------------------
'Python' 카테고리의 다른 글
Anaconda를 활용한 가상환경 만들기 (1) | 2021.11.14 |
---|---|
virtualenv를 활용한 가상환경 만들기 (0) | 2021.10.27 |
Flask를 설치하고 간단한 API 만들기 (0) | 2021.10.26 |