don't stop believing

Flask로 API 서버 만들기 (3) - User 테이블 만들기 본문

Python/Flask

Flask로 API 서버 만들기 (3) - User 테이블 만들기

Tongchun 2018. 11. 12. 11:59

Developing API Sample Server by Flask 

Original Post: How to structure a Flask-RESTPlus web service for production builds

Github: https://github.com/cosmic-byte/flask-restplus-boilerplate


Flask로 API 서버 만들기 (1) - 개발 환경 준비

Flask로 API 서버 만들기 (2) - config 와 실행 확인

Flask로 API 서버 만들기 (3) - User 테이블 만들기

Flask로 API 서버 만들기 (4) - Testing

Flask로 API 서버 만들기 (5) - User Operations

Flask로 API 서버 만들기 (6) - Security and Authentication

Flask로 API 서버 만들기 (7) - Route protection and Authorization

Flask로 API 서버 만들기 (8) - Extra tips (Makefiles)


이제 DB 를 만들어 보겠습니다.

model 폴더 아래 user.py 파일을 만들고 user 테이블을 만듭니다.

$ sudo vim ./app/main/model/user.py

user.py파일에 아래 script를 작성합니다.

from .. import db, flask_bcrypt class User(db.Model): """ User Model for storing user related details """ __tablename__ = "user" id = db.Column(db.Integer, primary_key=True, autoincrement=True) email = db.Column(db.String(255), unique=True, nullable=False) registered_on = db.Column(db.DateTime, nullable=False) admin = db.Column(db.Boolean, nullable=False, default=False) public_id = db.Column(db.String(100), unique=True) username = db.Column(db.String(50), unique=True) password_hash = db.Column(db.String(100)) @property def password(self): raise AttributeError('password: write-only field') @password.setter def password(self, password): self.password_hash = flask_bcrypt.generate_password_hash(password).decode('utf-8') def check_password(self, password): return flask_bcrypt.check_password_hash(self.password_hash, password) def __repr__(self): return "<user '{}'>".format(self.username)

User 클래스는 sqlalchemy의 db.Model 클래스를 상속받습니다.

user 데이블에 id, email, registered_on, admin, public_id, username, password_hash 컬럼을 만들어 줍니다.


이제 user 테이블을 사용하기 위해 manage.py 파일에 아래와 같이 import 합니다.

from app.main.model import user

manage.py 파일은 아래와 같습니다.

$ sudo vim manage.py
import os
import unittest

from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager

from app.main import create_app, db
from app.main.model import user

app = create_app(os.getenv('BOILERPLATE_ENV') or 'dev')

app.app_context().push()

manager = Manager(app)

migrate = Migrate(app, db)

manager.add_command('db', MigrateCommand)

@manager.command
def run():
    app.run()

@manager.command
def test():
    """Runs the unit tests."""
    tests = unittest.TestLoader().discover('app/test', pattern='test*.py')
    result = unittest.TextTestRunner(verbosity=2).run(tests)
    if result.wasSuccessful():
        return 0
    return 1

if __name__ == '__main__':
    manager.run()

migrateCommand로 db를 생성하겠습니다.

init 명령으로 초기화 합니다.

$ python manage.py db init
Creating directory /home/ngle/nGleAPI/migrations ... done
  Creating directory /home/ngle/nGleAPI/migrations/versions ... done
  Generating /home/ngle/nGleAPI/migrations/script.py.mako ... done
  Generating /home/ngle/nGleAPI/migrations/env.py ... done
  Generating /home/ngle/nGleAPI/migrations/alembic.ini ... done
  Generating /home/ngle/nGleAPI/migrations/README ... done
  Please edit configuration/connection/logging settings in '/home/ngle/nGleAPI/migrations/alembic.ini' before proceeding.

migrate 명령으로 db를 생성합니다.

$ python manage.py db migrate --message 'initial database migration'
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'user'
  Generating /home/ngle/nGleAPI/migrations/versions/faba1bd89e48_initial_database_migration.py ... done

upgrade 명령으로 적용합니다.

$ python manage.py db upgrade
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> faba1bd89e48, initial database migration

정상적으로 생성되었다면 main 폴더 아래 flask_boilerplate_main.db 파일이 생성됩니다.

이후로 database model이 변경될 경우 migrate 과 update 명령을 실행하면 됩니다.


여기까지해서 User 테이블을 만들었습니다.


tree 명령으로 디렉터리를 확인하면 아래와 같이 migrations 폴더가 생성됩니다.

$ tree
.
├── app
│   ├── __init__.py
│   ├── main
│   │   ├── config.py
│   │   ├── controller
│   │   │   └── __init__.py
│   │   ├── flask_boilerplate_main.db
│   │   ├── __init__.py
│   │   ├── model
│   │   │   ├── __init__.py
│   │   │   ├── __pycache__
│   │   │   │   ├── __init__.cpython-36.pyc
│   │   │   │   └── user.cpython-36.pyc
│   │   │   └── user.py
│   │   ├── __pycache__
│   │   │   ├── config.cpython-36.pyc
│   │   │   └── __init__.cpython-36.pyc
│   │   └── service
│   │       └── __init__.py
│   ├── __pycache__
│   │   └── __init__.cpython-36.pyc
│   └── test
│       ├── __init__.py
│       ├── __pycache__
│       │   └── test_config.cpython-36.pyc
│       └── test_config.py
├── manage.py
├── migrations
│   ├── alembic.ini
│   ├── env.py
│   ├── __pycache__
│   │   └── env.cpython-36.pyc
│   ├── README
│   ├── script.py.mako
│   └── versions
│       ├── 95f4f62caf8d_initial_database_migration.py
│       └── __pycache__
│           └── 95f4f62caf8d_initial_database_migration.cpython-36.pyc
├── __pycache__
│   └── manage.cpython-36.pyc
└── requirements.txt

15 directories, 26 files



Comments