본문 바로가기
Analysis Tips

[공공데이터] DB에 저장하고 Flask와 연결해보기

by dovah. 2021. 1. 10.
반응형

지난번에 API를 연결해서 데이터를 저장하는 것까지 진행했다.

 

하지만 단순히 데이터를 모으는 것에서 멈추는 게 아니라,

실제로 분석하고 웹으로 시각화하는 것이 목표이다.

 

그래서 이전에 수집했던 데이터들을 DB에 저장하고,

이걸 Flask를 통해서 DB 연결까지 해보는 것까지 이번에 해봤다.

 

사실 삽질을 많이 했다.

 

1. DB 셋팅

 

DB는 postgresql로 선정했다.

(그 이유는 지금 회사에서 사용하고 있으니까...)

 

개인 노트북의 경우 os가 ubuntu이기 때문에 설치하는 데 좀 애를 먹었다.

여러 블로그를 찾다가 한줄기 빛과 같은 아래 링크를 발견했고... 설치를 완료했다.

leop0ld.tistory.com/58

 

[Ubuntu] PostgreSQL 설치하고 사용하기

이번에는 Ubuntu에서 Database의 한 종류인 PostgreSQL을 설치해서 사용해보려고 합니다! 참고 - 우분투 PostgreSQL 설치, PostgreSQL Docs 1. PostgreSQL 설치하기 가장 먼저 $ sudo apt-get update 을 실행해줍..

leop0ld.tistory.com

 

아래는 설치된 데이터를 DB에 넣는 코드다.

import sqlalchemy
import pandas as pd
from sqlalchemy import create_engine
from glob import glob

engine = sqlalchemy.create_engine("postgresql://user:password@host:port/database")
#### (1)
data_list = []
for pkl in glob('/home/dovah/Documents/*.pkl'):
    data_list.append(pd.read_pickle(pkl))
    
temp_data = pd.concat(data_list)

temp_data.columns = ['price', 'create_year', 'trade_year', 'road_name', 
                     'road_building_code', 'road_region_code', 'road_serial_code',
                     'road_code', 'region_name', 'building_name', 'trade_month',
                     'trade_day', 'size', 'region_number', 'region_code', 'floor']
#### (2)
temp_data['price'] = temp_data['price'].apply(lambda x: int(x.replace(',', '')))
temp_data['size'] = temp_data['size'].apply(lambda x: float(x))

#### (3)
temp_data.to_sql(name = 'house_trade', con = engine, if_exists = 'append')

(1) 우선 데이터를 pickle 형태로 연도별로 저장했다.

glob를 통해서 특정 폴더에 있는 pickle 파일을 하나씩 읽고, 빈 리스트에 담아서

하나의 데이터프레임 형태로 만들었다.

 

그리고 변수 명이 모두 한글이었기 때문에, 영어명으로 변경했다.

 

(2) 가격이나, 평수의 경우 문자열 형식으로 되어 있기 때문에 숫자형태로 변경했다.

연도, 월, 일 등 추가로 변경을 해줘야했는데 급한 맘에 두개만 추가했다.

 

(3) 데이터프레임을 DB에 넣는 것은 한줄로 된다.

if_exists의 경우 기존의 테이블이 있는 경우 어떻게 할지에 대한 설정값이다.

지속적으로 데이터를 쌓기 위해서 'append'로 정했다.

 

*추가 dbeaver

개인적으로 dbeaver를 통해서 데이터가 잘 쌓이는 지 확인한다.

설치는 아래의 링크를 참고해서 진행했다.

앞서 postgresql을 설치하면서 설정한 사용자 정보를 통해서 연결할 수 있다.

 

dog-developers.tistory.com/127

 

DBeaver 설치 및 실행 (Window10)

1. 데이터베이스 Tool 설치하기 https://dbeaver.io/download/ Download | DBeaver Community Download Tested and verified for MS Windows 7/8/10, Linux and Mac OS X. DBeaver requires Java 1.8 or higher. W..

dog-developers.tistory.com

 

설치와 연결을 완료하면 아래의 그림처럼 데이터를 확인할 수 있다.

 

 

2. Flask와 연결해보기

 

사실 Flask와 연결해보자! 하고 결심한 건 아래 이후에 맘을 먹게 되었다.

dovah.tistory.com/30?category=884682

 

[Python] 파이썬 책 추천(깔끔한 파이썬 탄탄한 백엔드)

8월 중순에 이직한 이후 정신없이 프로트젝트에 참여하고 있는 요새다. 더군다나 이직하고 1주 지나마자 코로나가 다시 터지면서, 재택에 들어갔다. 최근에 다시 풀렸는데, 월급을 두번이나 받

dovah.tistory.com

개인적으로 기초가 많이 부족했는데 위의 책의 경우 그대로 따라해보면서 하기 쉬웠다.

 

우선 DB 연결 정보가 저장되어 있는 파일을 생성했다.

파일 이름은 config.py로 했다.

DB_URL = "postgresql://user:password@localhost:port/database"

 

 

 

1) app.py

from flask import Flask, jsonify, request, current_app
from flask.json import JSONEncoder
from sqlalchemy import create_engine, text


class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, set):
            return list(obj)
        return JSONEncoder.default(self, obj)
#### (1)

def create_app(test_config=None):
    app = Flask(__name__)
    if test_config is None:
        app.config.from_pyfile('config.py')
    else:
        app.config.update(test_config)        
#### (2)

    app.json_encoder = CustomJSONEncoder
    database = create_engine(app.config['DB_URL'], encoding='utf-8', max_overflow=0)
    app.database = database
    
#### (3)
    @app.route('/trade')
    def trade():
        return 'hello, world'
        
#### (4)-1
    @app.route('/trade/<int:trade_year>', methods=['GET'])
    def year_info(trade_year):
        temp_query = """
        select *
        from house_trade
        where trade_year = '{trade_year}'
        """
        query = temp_query.format(trade_year=str(trade_year))
        row = app.database.execute(text(query)).fetchall()

#### (4)-2
    	results = [list(r) for r in row]
        result_dict = {'results':results}
        return jsonify(result_dict)

    return app

 

(1) 책에서 있던 인코더 인데, 사실 잘 기억이 안난다.

일단 적어는 놨는데....

 

(2) 위에서 정의 했던 config.py를 통해서 db정보를 반영하는 부분이다.

 

(3) 루트를 설정하는 부분이다.

제대로 되는지 확인하기 위해서 예시로 진행했다.

 

localhost로 설정했고, 뒤에 루트 설정한 trade로 접속하면 설정한 값이 나타난다.

연결이 제대로 된것을 확인할 수 있다.

(4) 본격적으로 데이터를 노출하는 부분이다.

추가로 methods의 경우 데이터 값을 불러오는 경우 'GET', 값을 보내는 경우 'POST'로 설정한다.

 

(4)-1 주소로 받은 연도를 db에서 데이터를 추출하는 부분이다.

앞서 언급햇듯이 데이터를 db에 넣을 때 연도를 문자열값으로 넣어서 쿼리에서도 문자열로 들어가게했다.

(사실 이걸 놓쳐서 계속 삽질을 했다.)

 

(4)-2 추출된 데이터를 json 형태로 리턴하는 부분이다.

위에서 언급한 책의 경우 API 연결이기 때문에 json 형태로 리턴하게 만들었다.

 

(인코딩의 문제인지 한글이 제대로 표현안되고 있는데, 나중에 수정해야겠다.)

 

** 파이참 터미널에서 아래와 같이 입력하면 연결할 수 있다.

FLASK_ENV=development FLASK_APP=APP.PY FLASK_DEBUG=1 flask run

반응형

댓글