TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 웹개발>

[파이썬] Faker 라이브러리로 가짜 데이터 생성하기

by 기록자_Recordian 2025. 3. 20.
728x90
반응형
이전 내용

 

 

[파이썬] Streamlit 웹 개발 - 8: 대시보드 꾸미기

이전 내용 [파이썬] Streamlit 웹 개발 - 7: DB이전 내용 [파이썬] Streamlit 웹 개발 - 6: 저장 관련이전 내용 [파이썬] Streamlit 웹 개발 - 5: 로또 번호 생성 페이지이전 내용 [파이썬] Streamlit 으로 웹 페

puppy-foot-it.tistory.com


Faker 라이브러리란?

 

Faker는 Python에서 가짜 데이터를 생성하기 위한 라이브러리다. 개발, 테스트, 데이터베이스를 채우거나, 교육 목적 등에서 실제 데이터를 대신할 수 있는 임의의 데이터가 필요할 때 매우 유용하다. Faker는 이름, 주소, 이메일, 텍스트, 날짜 등 다양한 유형의 가짜 데이터를 다양한 언어와 지역 설정으로 생성할 수 있는 기능을 제공한다.

 

이전에 데이터분석을 위해 가상의 데이터를 생성했었는데, Faker 라이브러리를 알았다면 비교적 시간과 힘이 덜 들었을 것이다.

 

[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 1

프로젝트 개요 2차 프로젝트를 시작하게 되었다.이번에 해야할 프로젝트는 데이터를 이용한 대시보드 웹 페이지를 구축하는 것인데, 해당 대시보드에는 데이터를 분석하여 시각화 하는 작업이

puppy-foot-it.tistory.com

 

Faker 라이브러리를 사용하기 위해서는 먼저 해당 라이브러리를 설치해야 한다. (터미널에 입력)

pip install Faker

가짜 데이터를 생성하여
MySQL 데이터베이스에 넣기

 

이번엔 Faker 라이브러리를 이용해 가짜 데이터를 생성하고, 생성한 데이터를 MySQL 데이터베이스에 넣어보려고 한다.

앞서 말했듯이, DB 접근 정보는 코드에 직접 입력하면 보안 상의 문제가 있으므로, 직접 노출하지 않고 다른 파일에 넣어두고 불러와서 쓰는게 좋다.

이를 위해 secrets.toml 이라는 파일에 DB 관련 정보를 넣어두고, 파이썬 코드에서 이를 불러오는 방식으로 개선하였다.

[mysql]
dialect = "mysql"
host = "localhost"
port = "3306"
database = "tabledb"
user = "root"
password = "1234"
◆ toml 파일이란? (출처: 위키백과, 함께해요 파이썬 생태계)

TOML은 구성 파일을 위한 파일 형식이다. 시맨틱스를 최소한으로 쉽게 읽기/쓰기하도록 고안되었으며 딕셔너리에 모호함 없이 매핑하도록 설계되었다. 사양은 오픈 소스이며 커뮤니티 기여를 받는다. TOML은 수많은 소프트웨어 프로젝트에 사용되며 수많은 프로그래밍 언어에 구현되어 있다.

TOML의 문법은 주로 키 = 값 쌍, [섹션 이름], 그리고 #(주석)으로 이루어져 있다

TOML은 간단하고 명확하며, 구성 파일에 사용하기 쉬운 데이터 직렬화 언어다. 이 언어의 주 목적은 설정 파일을 위한 명확하고 읽기 쉬운 포맷을 제공하는 것이며, JSON, YAML과 같은 다른 데이터 직렬화 언어들과 비교될 때 인간이 읽기에 더 용이하며, 구문이 더 간결하다.

 

- DB에 연결하여 테이블을 생성하고 가짜 데이터를 생성하여 해당 테이블에 생성 후 조회하는 코드

import pandas as pd
from faker import Faker
import mysql.connector
from mysql.connector import Error

# MySQL 연결 정보 (secrets.toml에서 가져옴)
def get_db_connection():
    try:
        secrets = st.secrets["mysql"]
        connection = mysql.connector.connect(
            host=secrets["host"],
            database=secrets["database"],
            user=secrets["user"],
            password=secrets["password"]
        )
        if connection.is_connected():
            print("MySQL 데이터베이스에 성공적으로 연결되었습니다.")
        return connection
    except Error as e:
        st.error(f"데이터베이스 연결 실패: {e}")
        return None

# users 테이블을 생성하는 함수 정의
@st.cache_data # 변경 시에만 호출되도록 데코레이터 삽입
def create_users_table():
    conn = get_db_connection()
    if conn is None:
        return
    
    try:
        cursor = conn.cursor()
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS users (
                customer_id INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(100),
                age INT
            );
        """)
        conn.commit()
        st.success("users 테이블이 생성되었습니다.")
    except Error as e:
        st.error(f"users 테이블 생성 실패: {e}")
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()

# 더미 데이터 삽입 함수
def insert_fake_data(num_rows):
    conn = get_db_connection()
    if conn is None:
        return
    
    fake = Faker('ko_KR')
    try:
        cursor = conn.cursor()
        for _ in range(num_rows):
            name = fake.name()
            age = fake.random_int(min=18, max=80)
            cursor.execute(
                "INSERT INTO users (name, age) VALUES (%s, %s)",
                (name, age)
            )
        conn.commit()
        st.success(f"{num_rows}개의 가짜 데이터가 추가되었습니다.")
    except Error as e:
        st.error(f"데이터 삽입 실패: {e}")
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()

# 데이터 조회 함수
def fetch_users():
    conn = get_db_connection()
    if conn is None:
        return pd.DataFrame()
    
    try:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM users")
        result = cursor.fetchall()
        columns = ["customer_id", "name", "age"]
        df = pd.DataFrame(result, columns=columns)
        return df
    except Error as e:
        st.error(f"데이터 조회 실패: {e}")
        return pd.DataFrame()
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()

 

각 코드를 함수별로 나눠 설명해 본다.

get_db_connection(): MySQL 연결 함수

# MySQL 연결 정보 (secrets.toml에서 가져옴)
def get_db_connection():
    try:
        secrets = st.secrets["mysql"]
        connection = mysql.connector.connect(
            host=secrets["host"],
            database=secrets["database"],
            user=secrets["user"],
            password=secrets["password"]
        )
        if connection.is_connected():
            print("MySQL 데이터베이스에 성공적으로 연결되었습니다.")
        return connection
    except Error as e:
        st.error(f"데이터베이스 연결 실패: {e}")
        return None
  • 시크릿 정보 불러오기:
    secrets = st.secrets["mysql"] 코드를 통해 데이터베이스 연결에 필요한 비밀번호와 사용자 정보를 불러온다.
  • 데이터베이스 연결 시도:
    mysql.connector.connect 메소드를 사용하여 데이터베이스에 연결을 시도한다. 여기서 host, database, user, password는 시크릿 정보에서 가져온 값들이다.
  • 연결 성공 여부 확인:
    connection.is_connected() 메소드를 통해 연결이 성공적으로 이루어졌는지를 확인한다. 성공했다면, "MySQL 데이터베이스에 성공적으로 연결되었습니다."라는 메시지를 출력한다.
  • 연결 객체 반환:
    연결이 성공했으면 connection 객체를 반환한다.
  • 오류 처리:
    연결 과정에서 오류가 발생할 경우, except Error as e 블록이 실행되며, 해당 오류 메시지를 사용자에게 표시한다. 이 경우 함수는 None을 반환한다.

◆ create_users_table(): MySQL에 users 테이블 생성 함수

@st.cache_data # 변경 시에만 호출되도록 데코레이터 삽입
def create_users_table():
    conn = get_db_connection()
    if conn is None:
        return
    
    try:
        cursor = conn.cursor()
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS users (
                customer_id INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(100),
                age INT
            );
        """)
        conn.commit()
        st.success("users 테이블이 생성되었습니다.")
    except Error as e:
        st.error(f"users 테이블 생성 실패: {e}")
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()
  • 데코레이터 사용:
    @st.cache_data는 Streamlit 라이브러리의 데코레이터로, 이 함수의 결과를 캐싱한다. 데이터가 변경될 때만 함수를 다시 호출하여 새로운 결과를 생성한다.
  • 데이터베이스 연결:
    conn = get_db_connection()을 호출하여 데이터베이스에 연결을 시도힌다. 연결이 실패할 경우, 함수는 조기 반환하여 아무 작업도 수행하지 않는다.
  • 테이블 생성 요청:
    try 블록 내에서 cursor = conn.cursor()를 통해 커서를 만든다. 커서는 SQL 구문을 실행할 수 있는 객체다.
    cursor.execute()를 사용하여 users 테이블을 생성하는 SQL 명령어를 실행한다. 이 테이블은 customer_id, name, age라는 세 개의 컬럼을 갖습니다. 테이블이 이미 존재하는 경우, 아무 일도 일어나지 않는다.
  • 변경 내용 커밋:
    conn.commit()을 호출하여 변경된 내용을 데이터베이스에 저장한다. 테이블 생성이 완료되면 사용자에게 "users 테이블이 생성되었습니다."라는 성공 메시지를 표시한다.
  • 오류 처리:
    except Error as e 블록에서 테이블 생성 중 오류가 발생할 경우, 해당 오류 메시지를 사용자에게 출력한다.
  • 자원 해제:
    finally 블록 내에서 if conn.is_connected()를 통해 연결이 여전히 활성화되어 있는 경우, 커서를 닫고 데이터베이스 연결도 종료한다. 이는 자원 누수를 방지하는 데 중요하다.

◆ insert_fake_data(): 가짜 데이터를 생성하여 삽입하는 함수

def insert_fake_data(num_rows):
    conn = get_db_connection()
    if conn is None:
        return
    
    fake = Faker('ko_KR')
    try:
        cursor = conn.cursor()
        for _ in range(num_rows):
            name = fake.name()
            age = fake.random_int(min=18, max=80)
            cursor.execute(
                "INSERT INTO users (name, age) VALUES (%s, %s)",
                (name, age)
            )
        conn.commit()
        st.success(f"{num_rows}개의 가짜 데이터가 추가되었습니다.")
    except Error as e:
        st.error(f"데이터 삽입 실패: {e}")
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()
  • 데이터베이스 연결:
    conn = get_db_connection()을 호출하여 MySQL 데이터베이스에 연결을 시도한다. 연결에 실패한 경우, 함수는 조기 반환하여 어떤 작업도 수행하지 않는다.
  • Faker 라이브러리 사용:
    fake = Faker('ko_KR')를 통해 한국어로 가짜 데이터를 생성하는 Faker 객체를 생성한다. 이 객체는 무작위 이름과 나이 등을 생성하는 데 사용된다.
  • 가짜 데이터 삽입:
    try 블록 내에서 cursor = conn.cursor()를 만들어 SQL 쿼리를 실행할 수 있는 커서를 생성한다.
    for _ in range(num_rows): 루프를 통해 지정된 num_rows만큼 반복하여 가짜 데이터를 생성한다. 각 반복에서 name = [fake.name] 을 통해 무작위 이름을 생성한다.
    age = fake.random_int(min=18, max=80)를 통해 18세에서 80세 사이의 무작위 나이를 생성한다.
    cursor.execute()를 사용하여 생성된 이름과 나이를 users 테이블에 삽입한다. 쿼리는 %s 플레이스홀더를 사용하여 SQL 인젝션 공격을 방지한다.
  • 변경 내용 커밋:
    conn.commit()을 호출하여 삽입된 데이터의 변경 내용을 데이터베이스에 저장한다. 성공적으로 데이터가 추가되면 사용자에게 "X개의 가짜 데이터가 추가되었습니다."라는 성공 메시지를 표시한다.
  • 오류 처리:
    except Error as e 블록 내에서 데이터 삽입 중 오류가 발생할 경우, 해당 오류 메시지를 사용자에게 출력한다.
  • 자원 해제:
    finally 블록에서 if conn.is_connected()를 통해 연결이 활성 상태인 경우, 커서를 닫고 데이터베이스 연결을 종료한다. 이는 자원을 효율적으로 관리하는 데 필수적이다.

◆ fetch_users(): users 테이블에 저장된 데이터를 조회하여 Pandas DataFrame 형태로 반환하는 기능을 수행하는 함수

def fetch_users():
    conn = get_db_connection()
    if conn is None:
        return pd.DataFrame()
    
    try:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM users")
        result = cursor.fetchall()
        columns = ["customer_id", "name", "age"]
        df = pd.DataFrame(result, columns=columns)
        return df
    except Error as e:
        st.error(f"데이터 조회 실패: {e}")
        return pd.DataFrame()
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()
  • 데이터베이스 연결:
    conn = get_db_connection()을 호출하여 MySQL 데이터베이스에 연결을 시도한다. 연결이 실패할 경우, 빈 DataFrame을 반환하여 함수 실행을 종료한다.
  • 데이터 조회:
    try 블록 내에서 cursor = conn.cursor()를 통해 SQL 쿼리를 실행할 수 있는 커서를 생성한다.
    cursor.execute("SELECT * FROM users")를 사용하여 users 테이블의 모든 데이터를 조회한다.
  • 결과 가져오기:
    result = cursor.fetchall()을 호출하여 조회된 결과를 모두 가져온다. 이 결과는 튜플 형태의 리스트다.
  • Pandas DataFrame 생성:
    columns = ["customer_id", "name", "age"] 리스트를 정의하여 DataFrame의 컬럼명을 설정한다.
    df = pd.DataFrame(result, columns=columns)를 통해 조회된 결과를 DataFrame으로 변환한다. 이 DataFrame은 customer_id, name, age라는 세 개의 컬럼을 가진다.
  • 결과 반환:
    생성된 DataFrame df를 반환한다. 이를 통해 함수 호출자는 users 테이블의 데이터를 DataFrame 형태로 사용할 수 있다.
  • 오류 처리:
    except Error as e 블록에서 데이터 조회 중 오류가 발생할 경우, 오류 메시지를 사용자에게 출력하고 빈 DataFrame을 반환한다.
  • 자원 해제:
    finally 블록에서 if conn.is_connected()를 체크하여 연결이 여전히 활성 상태인 경우, 커서를 닫고 데이터베이스 연결을 종료한다. 이는 자원의 효율적인 관리에 중요하다.

Streamlit에 UI 만들어서 띄워보기

 

이제 가짜 데이터를 생성하여 테이블에 삽입하는 기능을 가진 코드를 웹페이지에서 사용할 수 있도록 구현하는 과정을 진행해 본다. 웹페이지에 구현하기 위하여 Streamlit을 사용한다.

st.title("MySQL + Faker 데이터 생성")
st.write(st.secrets)  # secrets.toml 내용 확인용

if st.button("users 테이블 생성"):
    create_users_table()

num_rows = st.number_input("추가할 가짜 데이터 개수", min_value=1, max_value=1000, value=10)
if st.button("가짜 데이터 추가"):
    insert_fake_data(num_rows)

if st.button("데이터 조회"):
    df = fetch_users()
    if not df.empty:
        st.dataframe(df)
    else:
        st.warning("조회된 데이터가 없습니다.")
  • 제목 표시:
    st.title("MySQL + Faker 데이터 생성")를 사용하여 웹 애플리케이션의 제목을 설정한다. 화면 상단에 "MySQL + Faker 데이터 생성"이라는 제목이 표시된다.
  • 시크릿 정보 출력:
    st.write(st.secrets)는 secrets.toml 파일의 내용을 확인하기 위해 사용된다. 이 부분은 보안을 고려하여 배포 전에 제거하는 것이 좋다.
  • users 테이블 생성 버튼:
    if st.button("users 테이블 생성"):에서 "users 테이블 생성"이라는 버튼을 표시하고, 사용자가 버튼을 클릭하면 create_users_table() 함수를 호출한다. 이 함수는 users 테이블을 생성한다.
  • 가짜 데이터 개수 입력:
    num_rows = st.number_input("추가할 가짜 데이터 개수", min_value=1, max_value=1000, value=10)는 사용자가 추가할 가짜 데이터의 개수를 입력할 수 있게 한다. 이 입력은 최소 1개, 최대 1000개이며, 기본값은 10이다.
  • 가짜 데이터 추가 버튼:
    if st.button("가짜 데이터 추가"):에서 "가짜 데이터 추가" 버튼을 표시하고, 사용자가 버튼을 클릭하면 insert_fake_data(num_rows) 함수를 호출한다. 이 함수는 입력된 수만큼 가짜 데이터를 users 테이블에 추가한다.
  • 데이터 조회 버튼:
    if st.button("데이터 조회"):에서 "데이터 조회" 버튼을 표시하고, 클릭하면 fetch_users() 함수를 호출하여 users 테이블의 데이터를 조회한다.
    - 조회된 데이터가 비어있지 않은 경우:
    st.dataframe(df)를 사용하여 DataFrame 형식으로 데이터를 표시.
    - 조회된 데이터가 비어있는 경우:
    st.warning("조회된 데이터가 없습니다.")를 사용하여 경고 메시지 표시.

전체 코드가 담긴 이 파일을 터미널에 실행 (streamlit run) 하면.....

 

★ toml 파일과 streamlit. 폴더

toml 파일을 만들고 Streamlit으로 불러올 때 한 가지 해줘야할 사항이 있다.

Streamlit에서 toml 파일을 불러올 때 .streamlit 이라는 폴더로부터 불러오기 때문에 toml 파일을 생성한 후에 해당 파일을 streamlit. 폴더에 넣어주면 해결된다.

 

이제 다시 실행해 보면,

 

테이블이 잘 생성되고, 가짜 데이터가 생성되어 해당 테이블에 삽입되고 이를 불러와 데이터프레임으로 만들고 화면으로 띄워주는 일련의 과정들이 잘 진행되는 것을 확인할 수 있다.


다음 내용

 

[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 7

이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 6이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 5이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 4

puppy-foot-it.tistory.com


[참고]

위키백과

함께해요 파이썬 생태계(https://wikidocs.net/230406)

728x90
반응형