728x90

fastapi 엑셀 파일 불러와서 뿌려주기 #4 - 검색


이제 단어 검색을 통해서 검색어에 해당하는 데이터만 보여주는 기능을 추가해봅니다.

 

문자열 검색의 경우에는 Series.str.contains 와 DataFrame.apply를 사용합니다.

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.contains.html

 

pandas.Series.str.contains — pandas 2.2.1 documentation

Fill value for missing values. The default depends on dtype of the array. For object-dtype, numpy.nan is used. For StringDtype, pandas.NA is used.

pandas.pydata.org

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.apply.html

 

 

"""
main.py
@제목: 메인 실행 파일
@설명: 메인 실행 파일

    작성일자        작성자
-----------------------
    2024.03.14    hiio420

"""
import math

from fastapi import FastAPI
from pydantic import BaseModel

from libs import ExcelUtils

# 엑셀 파일 불러오기

file_path = "F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx"
excel_utils = ExcelUtils()
df_dict = excel_utils.read_excel(file_path)

app = FastAPI()


class Item(BaseModel):
    data_id: int = 0
    page: int = 1
    limit: int = 10


@app.get("/")
def read_root(data_id: int = 0, page: int = 1, limit: int = 10,srch_txt=""):
    if page < 1:
        page = 0
    if limit < 10:
        limit = 10
    df = df_dict[data_id]
    df = df[df.apply(lambda row: row.astype(str).str.contains(srch_txt, case=False).any(), axis=1)]
    first_idx = (page - 1) * limit
    last_idx = first_idx + limit - 1
    total_size = df.shape[0]
    first_page = 1
    last_page = math.ceil(total_size / limit)

    df_sliced = df[first_idx:last_idx + 1].copy()

    df_sliced["번호"] = [i for i in
                       range(total_size - (page - 1) * limit, total_size - (page - 1) * limit - df_sliced.shape[0], -1)]
    data = []
    if df_sliced.shape[0] != 0:
        data = df_sliced.to_dict("records")

    return {"sheetName": excel_utils.sheet_names[data_id], "data_id": data_id, "page": page, "limit": limit,
            "first_page": first_page, "last_page": last_page, "firstIdx": first_idx, "lastIdx": last_idx,
            "totalSize": total_size,
            "data": data}

 

 

728x90
728x90

fastapi 엑셀 파일 불러와서 뿌려주기 #3 - Refactoring


 

"""
main.py
@제목: 메인 실행 파일
@설명: 메인 실행 파일

    작성일자        작성자
-----------------------
    2024.03.14    hiio420

"""
import math

import pandas as pd
from fastapi import FastAPI,Depends
from db.initDB import SessionLocal,get_user
from sqlalchemy.orm import sessionmaker,declarative_base,relationship,Session
# 엑셀 파일 불러오기
xlsx = pd.ExcelFile("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx")

# 각 시트 별 DataFrame 생성
df_cmStdTrm = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                            sheet_name=xlsx.sheet_names[0]).fillna("")
df_cmStdWd = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                           sheet_name=xlsx.sheet_names[1]).fillna("")
df_cmStdDmn = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                            sheet_name=xlsx.sheet_names[2]).fillna("")
df_cmStdTmplt = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                              sheet_name=xlsx.sheet_names[3]).fillna("")

# DataFrame을 Value로 하고 키가 int인 딕셔너리 생성
df_dict = {
    0: df_cmStdTrm,
    1: df_cmStdWd,
    2: df_cmStdDmn,
    3: df_cmStdTmplt
}

app = FastAPI()


@app.get("/")
def read_root(data_id: int = 0, page: int = 1, limit: int = 10,db: Session = Depends(get_db)):
    if page < 1:
        page = 0
    if limit < 10:
        limit = 10
    df = df_dict[data_id]
    first_idx = (page - 1) * limit
    last_idx = first_idx + limit - 1
    total_size = df.shape[0]
    first_page = 1
    last_page = math.ceil(total_size / limit)
    df_sliced = df[first_idx:last_idx + 1].copy()

    df_sliced["번호"] = [i for i in range(total_size - (page - 1) * limit, total_size - (page - 1) * limit - df_sliced.shape[0], -1)]
    data = []

    if df_sliced.shape[0] != 0:
        data = df_sliced.to_dict("records")
  
    
    return {"sheetName": xlsx.sheet_names[data_id], "data_id": data_id, "page": page, "limit": limit,
            "first_page": first_page, "last_page": last_page, "firstIdx": first_idx, "lastIdx": last_idx,
            "totalSize": total_size,
            "data": data}


if __name__ == "__main__":
    print(xlsx.sheet_names)
    print([(key, value.size) for key, value in df_dict.items()])

 

현재 까지 코드는 위와 같이 되어 있다 . 파일을 불러와서 쿼리스트링에 맞춰서 제공하는데 기능은 잘 작동하지만 코드가 너무 지저분한 느낌

 

파일을 읽어와서 딕셔너리로 변환하는 부분까지 우선 class 로 만들어서 사용하면 좋겠다는 생각을 했다.

 

1. 디렉토리 만들기


서버에서 사용하는 유틸성 있는 class나 함수들을 libs 디렉토리 안에 utils 디렉토리를 만들어서 관리하면 어떨까 한다.

 

pycharm에서 Python Package 만들기로 만들어 주자

 

 

 

 

2. FileUtils Class 만들기


먼저 excel 파일을 만들기 전에 파일을 읽어와서 파일에 대한 데이터를 가지고 있는 공통 class를 만들면 어떨까 싶어서

FileUtils Class를 만들어 보려고 한다.

 

1. 파일을 읽고

2. 파일 정보를 멤버 변수에 할당합니다.

3. class를 dict 와 json으로 변환 할 수 있도록 합니다.

4. 파일 사이즈를 Byte,KB,MB,GB 등로 변환합니다.

 

파일 정보는 

1. 파일이름

2. 파일 경로

3. 파일 확장자

4. 파일 사이즈

5. 파일 사이즈 + 용량단위

6. 파일 마지막 사용 날짜

7. 파일 생성 날짜

8. 파일 마지막 수정 날짜

입니다.

 

"""
FileUtils.py
@제목: 파일 정보 파일
@설명: 파일 정보를 읽어오는 Class 파일

    작성일자        작성자
-----------------------
    2024.03.15    hiio420

"""
import os
import pathlib
from datetime import datetime
import json
from typing import Any


class FileUtils:

    def __init__(self):
        self.filename: str | None = None
        self.path: str | None = None
        self.ext: str | None = None
        self.size: int | None = None
        self.size_unit: str | None = None
        self.access_dt: datetime | None = None
        self.created_dt: datetime | None = None
        self.modified_dt: datetime | None = None

    def read_file(self, path):
        self.path = path
        self.size = os.path.getsize(path)
        self.size_unit = self.calc_size_unit(self.size)
        self.access_dt = datetime.fromtimestamp(os.path.getatime(path))
        self.created_dt = datetime.fromtimestamp(os.path.getctime(path))
        self.modified_dt = datetime.fromtimestamp(os.path.getmtime(path))
        self.ext = pathlib.Path(path).suffix
        self.filename = pathlib.Path(path).stem

    def to_json(self) -> Any:
        return json.dumps(self.__dict__, default=str, indent=4)

    def to_dict(self) -> dict[str,Any]:
        return self.__dict__

    @staticmethod
    def calc_size_unit(size) -> str:
        byte_units = ["Bytes", "KB", "MB", "GB", "TB"]
        size_unit = ""
        for unit in byte_units:
            if size < 1024.0:
                size_unit = f"{round(size, 2)} {unit}"
                break
            else:
                size /= 1024.0
        return size_unit


if __name__ == '__main__':
    fileUtil = FileUtils()
    fileUtil.read_file('F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx')
    print(fileUtil.to_dict())

 

 

3. ExcelUtils class 만들기


이제 위에서 만든 FileUtils를 상속 받는 ExcelUtils class를 생성해 줍니다.

 

ExcelUtils는 파일 정보와 함께 엑셀 파일에 대한 간단한 정보를 멤버 변수에 저장합니다.

 

1. 엑셀파일 객체

2. 엑셀 시트 리스트 객체

3. 엑셀 시트 이름 리스트

4. DataFrame dictionary

 

"""
ExcelUtils.py
@제목: 엑셀 정보 파일
@설명: 엑셀 정보 Class 파일

    작성일자        작성자
-----------------------
    2024.03.15    hiio420

"""
from typing import List

import pandas as pd
from openpyxl.worksheet._read_only import ReadOnlyWorksheet
from pandas import ExcelFile, DataFrame

from libs.utils.FileUtils import FileUtils


class ExcelUtils(FileUtils):
    def __init__(self):
        super().__init__()
        self.xlsx_file: ExcelFile | None = None
        self.sheets: List[ReadOnlyWorksheet] | None = None
        self.sheet_names: List[str] | None = None
        self.df_dict: dict[int, DataFrame] | None = None

    def read_excel(self, file_path) -> dict[int, DataFrame]:
        self.read_file(file_path)
        self.xlsx_file = ExcelFile(file_path)
        self.sheets = self.xlsx_file.book.worksheets
        self.sheet_names = [sheet.title for sheet in self.sheets if sheet.sheet_state == "visible"]
        self.df_dict = {i: pd.read_excel(self.path, sheet_name=self.sheet_names[i]).fillna("") for i, n in
                        enumerate(self.sheet_names)}

        return self.df_dict


if __name__ == '__main__':
    excelUtils = ExcelUtils()
    excelUtils.read_excel('F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx')
    print(excelUtils.to_dict())

 

 

이전과 달라진 점이 있다면 숨긴 처리된 시트이름도 모두 가져왔으나, sheet_state를 통해서 보이도록 설정된 시트들 이름만 가져와 dictionay를 만든다는 점입니다.

 

4. main.py 적용


이제 기본에 있던 코드를 삭제하고 새로 만든 ExcelUtils class로 대체합니다.

"""
main.py
@제목: 메인 실행 파일
@설명: 메인 실행 파일

    작성일자        작성자
-----------------------
    2024.03.14    hiio420

"""
import math

from fastapi import FastAPI

from libs import ExcelUtils

# 엑셀 파일 불러오기

file_path = "F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx"
excel_utils = ExcelUtils()
df_dict = excel_utils.read_excel(file_path)

app = FastAPI()


@app.get("/")
def read_root(data_id: int = 0, page: int = 1, limit: int = 10):
    if page < 1:
        page = 0
    if limit < 10:
        limit = 10
    df = df_dict[data_id]
    first_idx = (page - 1) * limit
    last_idx = first_idx + limit - 1
    total_size = df.shape[0]
    first_page = 1
    last_page = math.ceil(total_size / limit)
    df_sliced = df[first_idx:last_idx + 1].copy()

    df_sliced["번호"] = [i for i in range(total_size - (page - 1) * limit, total_size - (page - 1) * limit - df_sliced.shape[0], -1)]
    data = []

    if df_sliced.shape[0] != 0:
        data = df_sliced.to_dict("records")


    return {"sheetName": excel_utils.sheet_names[data_id], "data_id": data_id, "page": page, "limit": limit,
            "first_page": first_page, "last_page": last_page, "firstIdx": first_idx, "lastIdx": last_idx,
            "totalSize": total_size,
            "data": data}


728x90
728x90

fastapi 엑셀 파일 불러와서 뿌려주기 #2


이전 포스팅에서 파일을 불러와 sheetNames와 data 전체를 응답하는 것을 만들었습니다.

이제 페이징을 할 수 있게끔 page 번호와 표시할 목록 개수를 요청해서 응답 받는 것을 해보겠습니다.

 

 

1. Pagination


페이징 처리를 하기위해서 기본적으로 요청 받는 파라미터는 페이지 번호와 출력 갯수입니다.

 

저는 페이지 번호를 page 출력 갯수를 limit으로 해서 쿼리스트링을 포함시켜 주겠습니다.

@app.get("/")
def read_root(id: int = 0,page:int = 1, limit:int = 10):
    data = df_dict[id].to_dict("records")
    return {"sheetName": xlsx.sheet_names[id], "data": data}

page의 기본값은 1 limit은 10입니다.

 

두 값을 통해서 DataFrame을 slicing 해야합니다.

그러기 위해서 첫 index값과 마지막 index값을 정해야합니다.

 

@app.get("/")
def read_root(data_id: int = 0, page: int = 1, limit: int = 10):
    if page < 1:
        page = 0
    if limit < 10:
        limit = 10
    df = df_dict[data_id]
    first_idx = (page - 1) * limit
    last_idx = first_idx + limit - 1
    total_size = df.shape[0]
    first_page = 1
    last_page = math.ceil(total_size / limit)
    df_sliced = df[first_idx:last_idx + 1].copy()

    df_sliced["번호"] = [i for i in range(total_size - (page - 1) * limit, total_size - (page - 1) * limit - df_sliced.shape[0], -1)]
    data = df_sliced.to_dict("records")
    return {"sheetName": xlsx.sheet_names[data_id], "data_id": data_id, "page": page, "limit": limit,
            "first_page": first_page, "last_page": last_page, "firstIdx": first_idx, "lastIdx": last_idx,
            "totalSize": total_size,
            "data": data}

 

기본값 미만인 값이 들어올경우 기본값으로 바꾸는 조건문을 작성해 줍니다.

 

첫 index 값은 (page-1) * limit 

마지막 index값은 첫index + limit -1 입니다.

새로운 번호를 매기기 위해서 total size를 구해줍니다.

 

id 라는 변수는 python에 이미 지정된 함수가 있기때문에 되도록 사용하지 않도록 하기 위해 data_id 라는 값으로 변경했습니다.

 

response 시에 data,sheetName 이외에도 전달받은 값과 함께 first_page,last_page,first_idx,last_idx,total_size를 추가해 주었습니다.

 

 

2. Swagger로 데이터 요청 응답


 

FastAPI Swagger를 이용한 API 문서를 제공합니다.

 

 

3. Pycharm Http request 기능


728x90
728x90

엑셀 파일 불러와서 뿌려주기 #1


파일로 저장되어 있는 공공표준용어 데이터를 읽어와서 url로 접속시 해당 내용을 뿌려주는 작업을 진행해보자!!

 

먼저 , 파일을 불러오기 위한 방법으로는 pandas를 사용한다.

진행 순서는 아래와 같다.

 

1. pandas ExcelFile 로 엑셀 파일을 불러와서 sheet 이름들을 가져온다.

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.ExcelFile.html

 

pandas.ExcelFile — pandas 2.2.1 documentation

A file-like object, xlrd workbook or openpyxl workbook. If a string or path object, expected to be a path to a .xls, .xlsx, .xlsb, .xlsm, .odf, .ods, or .odt file.

pandas.pydata.org

2. 각 시트 별로 read_excel로 데이터 프레임을 만들어 준다.

3. 데이터를 정렬 시키고 새 index를 부여한다.

4. 각 데이터프레임을 api query string에 맞춰 return 시킨다.

5. 최소 출력 row 수는 10개이다.

 

 

1. 파일 불러오기


 

pandas에서 엑셀 파일을 불러오기 위해서는 openpyxl 패키지가 필요합니다.

 

requirements.txt에 추가하고 설치합니다.

 

openpyxl==3.1.2

 

프로젝트 디렉토리에 upload 디렉토리를 만들고 파일을 넣어줍니다.

 

이제 기존에 있던 소스 코드를 지우고 새로 작성해 보겠습니다.

 

pandas를 import 하고 ExcelFile의 인자값으로 파일이 위치한 경로를 절대경로로 넣어줍니다.

 

import pandas as pd

xlsx = pd.ExcelFile("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx")

 

이제 ExcelFile에서는 sheet_names를 통해서 이 엑셀 파일의 sheet들의 이름 정보를 리스트로 가져올 수 있습니다.

if __name__ == "__main__": 을 통해서 print 찍어 보겠습니다.

 

import pandas as pd

xlsx = pd.ExcelFile("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx")



if __name__ == "__main__":
    print(xlsx.sheet_names)
    

 

 

실제 파일과 비교해 보겠습니다.

실제 파일에서 보이는 sheet는 총 3개이지만 sheet_names로 표시되는 element 수는 4개입니다.

엑셀 파일에서 숨기기 취소를 보면 '공통표준도메인 초안 1' 숨기기 처리 된것을 볼 수 있습니다.

 

 

이제 이 파일에 들어있는 시트별로 데이터프레임을 만들어 주고

딕셔너리를 만들어 줍니다.

"""
main.py
@제목: 메인 실행 파일
@설명: 메인 실행 파일

    작성일자        작성자
-----------------------
    2024.03.14    hiio420

"""

import pandas as pd

# 엑셀 파일 불러오기
xlsx = pd.ExcelFile("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx")

# 각 시트 별 DataFrame 생성
df_cmStdTrm = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",sheet_name=xlsx.sheet_names[0])
df_cmStdWd = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",sheet_name=xlsx.sheet_names[1])
df_cmStdDmn = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",sheet_name=xlsx.sheet_names[2])
df_cmStdTmplt = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",sheet_name=xlsx.sheet_names[3])


# DataFrame을 Value로 하고 키가 int인 딕셔너리 생성
df_dict = {
    0:df_cmStdTrm,
    1:df_cmStdWd,
    2:df_cmStdDmn,
    3:df_cmStdTmplt
}



if __name__ == "__main__":

    print(xlsx.sheet_names)
    print([(key,value.size) for key,value in df_dict.items()])

 

 

 

2. Get Routing


이제 df_dict에 있는 데이터를 Routing 하는 함수를 만들어 줍니다.

@app.get("/")
def read_root(id: int = 0):
    data = df_dict[id].to_dict("records")
    return {"sheetName": xlsx.sheet_names[id], "data": data}

아직 API에 대한 정확한 정보를 작성하지는 않았습니다.

 

쿼리 스트링으로 id 값을 받고 기본값으로는 0을 입력합니다.

 

응답으로는 data와 함께 sheet 명을 추가적으로 전달합니다.

 

서버를 실행하고 http://127.0.0.1:4882/ 접속해보면

 

정상적으로 출력 되는 것을 볼 수 있습니다.

 

그럼 query String 을 url에 추가로 입력에 id 값을 1로 하여 보내봅니다.

 

 

서버 에러가 나버렸습니다.

서버 로그를 보면

ValueError: Out of range float values are not JSON compliant 에러가 발생했습니다.

Nan이나 null 값이 Dataframe에 있기때문에 결측치 값 처리를 해줘야 할거 같습니다.

 

Pandas fillna를 이용해 결측치를 모두 빈문자열로 만들어 줍니다.

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.fillna.html

 

pandas.DataFrame.fillna — pandas 2.2.1 documentation

If method is specified, this is the maximum number of consecutive NaN values to forward/backward fill. In other words, if there is a gap with more than this number of consecutive NaNs, it will only be partially filled. If method is not specified, this is t

pandas.pydata.org

# 각 시트 별 DataFrame 생성
df_cmStdTrm = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                            sheet_name=xlsx.sheet_names[0]).fillna("")
df_cmStdWd = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                           sheet_name=xlsx.sheet_names[1]).fillna("")
df_cmStdDmn = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                            sheet_name=xlsx.sheet_names[2]).fillna("")
df_cmStdTmplt = pd.read_excel("F:\\[01]project\\commonStandardTerm\\upload\\(붙임)공공데이터 공통표준용어(2022.7월).xlsx",
                              sheet_name=xlsx.sheet_names[3]).fillna("")

 

이후 다시 서버를 reload 하고 

 

접속해 봅니다.

 

이제 정상적으로 출력 되는 것을 볼 수 있습니다.

 

 

728x90
728x90

1. 구성 계획


개발환경은 Window에서 진행되고 Backend는 python fastapi Frontend는 nextjs를 사용해볼 계획이다. 배포까지 하면 좋겠지만 추후로 미루기로 하자.

IDE는 Pycharm을 쓸예정이다. (VSCode를 써보 되긴하지만, Jetbrain을 결제해서 쓰고 있어서 Pycharm을 쓰기로 결정 Front도 WebStorm을 쓸 예정이다.

 

 

2. 개발환경


 

OS : Window 10

Python : 3.10

으로 anaconda로 가상환경을 구성하지 않고 venv로 구성을 한다.

 

1. 프로젝트 만들기


 

 

Pycharm 실행 후 New Project를 선택하면 Python관련 프로젝트에 FastAPI가 있지만 Pure Python으로 진행한다.

프로젝트 이름은 commonStandartTerm으로 만들고 Location을 지정해준다.

 

 

다음으로 가상환경을 만들어 준다. Python3.10이 설치되어 있지않다면

Base Python에서 아래 화살표를 클릭하면 download and install 할 수 있다.

 

 

Location을 적절한 곳으로 잡아주고 Create를 해준다.

 

 

프로젝트가 생성되었다.

아직은 아무것도 없다.

 

먼저 필요한 패키지들을 설치해 보자.

 

2. 패키지 설치


패키지의 경우 프로젝트를 진행하면서 추가적으로 설치하겠다. 기본적으로 설치할 패키지는 FastAPI, unvicorn,pandas,pytest 이다.

 

터미널에 pip 로 설치할 수 있지만 requirements.txt 파일을 생성해 Pycharm 기능으로 설치해 보자.

 

requirements.txt파일을 생성 후 아래와 같이 입력한다.

fastapi==0.110.0
uvicorn[standard]==0.28.0
pandas==2.2.1
pytest==8.1.1

 

입력 후 저장하면 python에 메세지가 나타나고 설치 할 것인지 물어본다.

 

install requirements 를 클릭하면 패키지들이 설치된다.

 

2. Fast API 실행해보기


https://fastapi.tiangolo.com/ko/#_5

 

FastAPI 사이트에서 제공하는 예제 코드를 main.py에 넣고, 실행해보자.

from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}
uvicorn main:app --reload

 

 

port 8000으로 접속하면 Hello World를 볼 수 있다.

 

#. Pycharm 실행 화경 만들기

터미널에서 

uvicorn main:app --reload

으로 실행할 수도 있지만, IDE를 사용하고 있으니까 실행환경을 수정해서 Pycharm에서 Run 할 수 있게 해보자.

 

PyCharm 우측 상단에 Run 버튼 옆에 Current File을 클릭하면 드롭 박스가 열리고 Edit Configurations 를 통해 실행 환경을 구성할 수 있다.

 

 

+ 버튼을 누르면 실행환경을 구성할 수 있는 목록이 나타나는데 FastAPI를 선택하자

 

 

 

main.py 위치를 정해주고 apply 한다음 Run 해보자.

 

 

Error : LookupError: unknown encoding: x-windows-949


실행 시 Encoding 문제가 발생한다면, 프로젝트 세팅에서 encoding을 바꿔준다.

 

1. settings > Editor > File Encodings > Project Encoding 을 UTF-8

 

2. settings > Editor > Console > Default Encoding 을 UTF-8

 

 

바꾼 후 다시 실행해보면

 

 

정상 적으로 실행되고 다시 접속하면

이전과 같은 화면을 볼 수 있다.

728x90
728x90

 

0. Intro


최근 프로젝트를 진행하면서 단어 정리나 용어 정의를 공공데이터 공통표준용어에 맞춰 하는일이 생겼다.

 

"공공데이터 공통표준용어"는

행정안전부고시 제2020-42

를 보면

" 공공데이터를 누구나 같은 의미로 이해하고 같은 방식으로 사용할  있도록 공통표준용어를 정의함"이라고 나와있다. 

 

기존에는 공공데이터 포털에서 제공하는 엑셀 파일에서 필요한 부분을 "찾기"를 통해서 검색해서 사용했는데, 이 데이터를 바탕으로 검색을 좀 더 수월하게 하는 웹페이지를 만들면 어떨까 싶기도 하고 최근에는 JAVA와 Oracle로만 프로그래밍을 하다보니 python과 mariaDB에 대한 기억도 가물가물해지는 감도 있어서 작은 개인 프로젝트로서 진행해 보면 어떨까 싶어 시작하게 되었다.

 

1. 요구사항


이 프로젝트에 필요한 요구사항은 기본적으로 "검색한 단어를 포함하는 공공데이터 공용표준용어의 데이터를 출력"한다는 것이다.

 

시나리오는 

1. 검색어를 입력한다.

2. 조회버튼을 클릭한다.

3. 검색어를 포함(또는 전체)를 조회하여 표로 보여준다.

4. 페이징 을 할수 있어야 한다.

와 같이 길지는 않다.

 

추가적인 기능은 프로젝트를 하면서 붙여나가기로 해보고 개발환경을 먼저 구성해보자.

728x90
728x90

1. MariaDB Server 다운로드

DB 버전 : 11.3.2 Community Server

https://mariadb.org/download/?t=mariadb&p=mariadb&r=11.3.2&os=Linux&cpu=x86_64&pkg=tar_gz&i=systemd&m=blendbyte

 

Download MariaDB Server - MariaDB.org

REST API Release Schedule Reporting Bugs … Continue reading "Download MariaDB Server"

mariadb.org

 

 

2. 설치

groupadd mysql
useradd -g mysql mysql
 cp mariadb-11.3.2-linux-systemd-x86_64.tar.gz /usr/local/mariadb-11.3.2-linux-systemd-x86_64.tar.gz

cd /usr/local
tar -zxvpf mariadb-11.3.2-linux-systemd-x86_64.tar.gz
ln -s mariadb-11.3.2-linux-systemd-x86_64 mysql
cd mysql
./scripts/mariadb-install-db --user=mysql
chown -R root .
chown -R mysql data

 

3. 환경 변수 추가

vi ~/.bashrc
export PATH=$PATH:/usr/local/mysql/bin/
source ~/.bashrc

 

 

4. 자동 실행

cp support-files/mysql.server /etc/init.d/mysql.server

cp support-files/systemd/mariadb.service /usr/lib/systemd/system/mariadb.service

mkdir /etc/systemd/system/mariadb.service.d/

cat > /etc/systemd/system/mariadb.service.d/datadir.conf <<EOF
[Service]
ReadWritePaths=/usr/local/mysql/data
EOF

systemctl daemon-reload

systemctl start mariadb.service

systemctl enable mariadb.service

 

 

 

에러 

#1 mariadb: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory

$sudo ln -s /usr/lib/x86_64-linux-gnu/libncursesw.so.6.2 /usr/lib/x86_64-linux-gnu/libncursesw.so.5

$ sudo ln -s /usr/lib/x86_64-linux-gnu/libncurses.so.6.2 /usr/lib/x86_64-linux-gnu/libncurses.so.5

$ sudo ln -s /usr/lib/x86_64-linux-gnu/libncursesw.so.6.2 /usr/lib/x86_64-linux-gnu/libtinfo.so.5
참고 : https://mariadb.com/kb/en/installing-mariadb-binary-tarballs/
728x90

'모음집 > Linux' 카테고리의 다른 글

[Linux] Raspberry Pi FTP 설정  (0) 2024.03.26
[Linux] 리눅스 명령어 모음집 #1 / 우분투 /  (0) 2022.01.20
728x90

https://docs.docker.com/compose/

 

Docker Compose overview

Learn how to use Docker Compose to define and run multi-container applications with this detailed introduction to the tool.

docs.docker.com

version: "3"
services:
  mariadb:
    image: tobi312/rpi-mariadb:10.6-alpine
    environment:
      - MYSQL_ROOT_PASSWORD="<ROOT PASSWORD>"
      - TZ="Asia/Seoul"
    ports:
      - 3307:3306
    volumes:
      - ~PATH/data:/var/lib/mysql
      - ~PATH/log:/var/log/maria
      - ~PATH/conf.d:/etc/mysql/conf.d:ro
    restart: always
    container_name: mariadb

 

728x90

'study > docker' 카테고리의 다른 글

[docker] 도커 설치 우분투 / docker install on ubuntu  (0) 2023.01.30
[Docker] ssh 설치  (0) 2023.01.13
728x90

1. 현재 Linux 버전 확인

 

2. python download

 

wget https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz

 

2-1 패키지 설치

sudo apt install libssl-dev libncurses5-dev libsqlite3-dev libreadline-dev libtk8.6 libgdm-dev libdb4o-cil-dev libpcap-dev

 

3. 압축 풀기

tar -xvf Python-3.10.13.tgz

 

4. 이동

cd Python-3.10.13/

 

5. Configure

./configure

 

5-1 . Error : configure: error: no acceptable C compiler found in $PATH

 sudo apt-get install gcc

 

gcc 설치 후 다시 ./configure

 

6. Make

sudo make install

 

6-1 Command 'make' not found, but can be installed with:

sudo apt install make

그리고 다시 sudo make install

 

6-2 Command  returned non-zero exit status 1.

sudo apt-get install virtualenv

그리고 다시 sudo make install

 

6-3 ModuleNotFoundError: No module named 'zlib'

sudo apt-get install zlib1g zlib1g-devel

그리고 다시 sudo make install

 

7. Symbolic link 만들기

 

sudo ln -s /usr/local/bin/python3.10 python
sudo ln -s /usr/local/bin/pip3.10 pip
728x90

'Programming > Python' 카테고리의 다른 글

[Python] Tensoflow F1 score metrics  (0) 2022.09.22
[python]무작위 페이크 이름 생성기  (0) 2022.05.13
[#1] 파이썬에 대하여 개인적인 생각  (0) 2021.12.24
[#0] 파이썬  (0) 2021.12.06
728x90

라즈베리파이


  1. 구입처 기록
    https://www.devicemart.co.kr/goods/view?no=12553062
    https://www.eleparts.co.kr/promotion/cate_event?event_seq=1622

Dart


  1. json데이터 사용시 dart:convert 이용
  2. jsonDecode 를 사용해 json 문자열을 decode 한다.
  3. var 타입 또는 Map<String,dynamic>으로 받는다.
  4. 배열형태로된 문자열의 경우에는List 로 받아 준다.
  5. stream 사용법 추가 공부를 해보자 async* yield
  6. stream then 사용 : first,laset,isEmpty,length
  7. random 함수는 dart:math에 있음
  8. hash 류는 dart:collection

JAVA - Spring


  1. Poi Excel cell값을 가져올때 type을 잘 보고 가져오자.

Flutter


  1. 초기 생성시 lib > main.dart 파일
  2. lib 폴더에만 집중하자.
  3. root 디렉토리 > pubspec.yaml 파일 flutter에서 쓰이는 패키지,이미지,폰트등
  4. dart 파일 첫 줄 import 문 > java 와 비슷
  5. import "package:flutter/material.dart"
728x90

'study > TIL' 카테고리의 다른 글

[TIL] 2024-05-13 AWS  (0) 2024.05.13
[TIL] 2024-05-10 AWS  (0) 2024.05.10
[TIL] 2024-05-09 , 자바스크립트 정규표현식 사이트 / catalina.out 라인 끊어서 저장  (0) 2024.05.09
[TIL#2]  (0) 2023.04.27
[TIL] Day #1  (0) 2023.04.26

+ Recent posts