앞의 포스트에서 Flask 웹 프레임워크를 이용해 Hello, Flask!를 출력하는 파이선을 이용한 웹 프로그램을 작성하였고 Blueprint를 이용한 모듈화도 테스트했다.
그리고 DB연동을 위해 MariaDB까지 설치를 마쳤다.
이젠 파이썬에서 사용 가능한 ORM (Object Relational Mapping) 라이브러리를 사용하여 파이썬 Flask 어플리케이션의 클래스와 속성을 데이터베이스의 테이블-컬럼 구조와 매핑하고 DB를 자동으로 구성관리하는 방법에 대해 포스팅한다.
다양한 SW 개발언어에서 데이터베이스에 데이터를 저장하고 조회하기 위해 문자열 변수에 데이터베이스 질의어인 SQL을 만들어 저장하고 DBMS에서 실행하고 그 결과를 리턴받는 기능을 지원한다.
하지만 서로 서버에서 실행되는 이질적인 개발언어 언어(C, Java, PHP, Python 등)와 웹 브라우저에 의해 해석되고 실행되는 HTML, Java Script, CSS그리고 DBMS에서 해석하고 실행하는 SQL이 뒤죽박죽 된 소스코드를 작성하고 보는 것은 무척이나 괴로운 일이다.
그래서 많은 개발언어와 웹 프레임워크들은 개발언어와 HTML과 스크립트 그리고 SQL을 각각 격리하고 매핑할 수 있는 기능들을 제공한다.
그 중에서 ORM은 개발언어와 DB의 데이터를 조회하는 SQL 그리고 DB의 테이블을 객체지향언어에서 등장하는 클래스(Class)로 추상화하고 컬럼은 속성(Property)으로 그리고 Select, Insert, Delete, Update에 해당되는 SQL문은 메소드(Method)로 추상화하는 것을 지원한다고 이해해도 무방하다 하겠다.
파이썬의 Flask 웹 프레임워크에서 ORM을 사용하기 위해서는 두개의 파이썬 패키지를 설치해야 한다.
먼저 Flask-Migrate라는 패키지를 pip3 명령을 이용하여 다음과 같이 설치한다. 단 venv를 이용한 가상환경으로 진입한 뒤 실행한다.

이 Flask-Migrate 패키지를 설치하면 파이썬의 ORM 라이브러리인 alembic, SQL-Alchemy가 함께 설치된다. (pip3 list 명령으로 확인가능함)
그리고 Flask 웹프레임워크로 작성된 파이썬 어플리케이션에서 MariaDB에 접속하기 위한 드라이버를 추가로 설치해야 한다. Java에서 DB에 접속하기 위한 JDBC 드라이버와 같은 수준의 드라이버라고 생각하면 된다.
다음과 같이 pip3 명령을 이용해 mysql-connector-python 패키지를 설치한다.

마찬가지로 pip3 list 명령을 통해 설치된 패키지를 확인할 수 있다.
다음은 Flask 웹 프레임워크로 작성된 어플리케이션(이 포스트에서는 어플리케이션 이름이 blogger 임)에서 사용할 MariaDB의 데이터베이스와 계정을 다음과 같이 만들어준다. MariaDB 접속은 다음의 명령을 이용하면 된다.
$ mysql -u root -p
Enter password: <이하생략> |
그리고 다음과 같이 데이터베이스와 계정을 생성하고 생성한 계정에게 데이터베이스의 전권을 준다.

create user 문에서는 계정을 localhost에서만 접속할 수 있는 flask라는 계정을 만든다. 그리고 비밀번호를 x~~~@로 초기화한다.
create database 문에서는 blogger 라는 DB를 기본설정에 의해 생성한다.
grant 에서는 blogger DB의 모든 객체에 대해 localhost의 flask라는 계정에게 전권(All privileges)을 준다.
생성된 DB, 계정 그리고 계정에 부여된 권한은 다음과 같이 확인할 수 있다.

위 화면과 같이 잘 보인다면 작업이 성공한 것이다.
다음은 ORM 연동 시 사용할 DB의 정보를 blogger 어플리케이션의 최상위 디렉토리에 생성하는 것이다.
다음과 같이 config.py라는 파일을 만들어 준다.

이 config.py는 blogger 어플리케이션의 __init__.py 파일 등에서 MariaDB 등의 접속 정보가 필요할 때 import 하여 사용하게 된다.
user와 password에는 앞에서 MariaDB에 접속하여 생성한 계정인 flask와 x~~~@가 설정되어 있고 database 항목에는 blogger가 설정되어 있다.
host에는 flask가 실행중인 서버와 mariadb가 설치된 서버가 동일하므로 localhost에 해당되는 ip인 127.0.0.1이 설정되어 있다.
다음은 ORM의 핵심인 객체와 데이터베이스를 매핑하는 모델링 파일을 작성해야 한다. 이 파일은 어플리케이션의 최상위 경로에 다음과 같이 생성해주면 된다.

이 models.py 파일은 Flask-Migrate에 포함된 SQL Alchemy와 Alembic을 이용해 Flask 웹프레임워크 어플리케이션의 클래스와 MariaDB의 테이블을 매핑하고 실제로 DB에 테이블을 생성하거나 클래스의 구조가 변경되었을 때 테이블 구조도 변경할 때 사용되는 모델링 파일이다.
from 문에서 db라는 파이썬 라이브러리를 import 한다.
그리고 board라는 클래스에서 rowid, subject, content, create_date라는 속성의 데이터 유형을 정의한다. 그리고 아래에 있는 reply라는 클래스도 동일하게 작업한다. 이 클래스들과 속성은 Flask-Migrate 패키지의 특정 명령(뒤에서 설명함)어가 config.py에 정의한 blogger DB에 flask계정으로 접속해 board 테이블과 reply 테이블을 생성한다.
만약 models.py가 변경되었다면 그에 따라 테이블의 구조도 변경(alter)할 수 있다.
그리고 어플리케이션(이 포스트에서는 blogger)의 __init__.py 파일을 다음과 같이 수정하여야 한다.

이 소스에 적용된 코드는 추후에 설명한다. 어플리케이션의 소스코드에 flask_migrate와 연관된 코드가 추가되어 있지 않으면 models.py에 정의된 클래스에 매핑될 테이블이 생성되지 않는다.
즉 flask_migrate 패키지를 이용해 DB의 테이블을 생성하려면 위에 노락색 박스의 소스코드가 모두 작성되어 있어야한다. 뒤에서 실행할 flask db init 명령이나 flask db migrate 명령, flask db upgrade 명령이 클래스의 모델링 정보를 models.py 파일에서 flask 명령이 직접 읽어오는 것이 아니라 어플리케이션을 통해 전달받는 것으로 보인다.
__init__.py 파일을 수정했다면 이제 DB를 초기화하고 migrate 한 뒤 upgrade하여 실제 DB에 models.py에 정의된 클래스와 매핑될 테이블을 만들어보자.
다음과 같이 config.py가 위치한 곳에서 (어플리케이션 경로가 있는 디렉토리) flask db init 명령을 실행한다.

flask db init 이라는 명령을 실행하면 config.py와 어플리케이션에 해당되는 폴더 내의 models.py를 이용하여 버전관리와 DB 마이그레이션을 위한 정보를 저장하는 파일들을 생성한다.
그리고 실제 MariaDB에 접속하여 데이터베이스에 alembic_version 이라는 테이블이 생성된 것을 확인할 수 있다.
다음은 flask db migrate 를 실행한다.

다음은 flask db upgrade 명령을 실행해 실제 models.py 파일에 정의된 Class에 해당되는 테이블을 생성한다.

실제 테이블을 생성하는 DDL 문이 실행된다는 메시지를 볼 수 있다.
실제 MariaDB에 접속하여 생성된 테이블을 확인한다.

다음 포스트 부터 본격적인 게시판의 입/출력/조회 화면을 위한 코드를 작성해 보자.
#flask-migrate #SQLAlchemy