Files
static/conf/db_schema.py

260 lines
9.0 KiB
Python

# db_schema.py
import os
import yaml
from sqlalchemy import Table, Column, Date, Integer, String, Float, Text, MetaData, UniqueConstraint, DateTime, Time, PrimaryKeyConstraint, Index
from sqlalchemy.sql import func
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
CONFIG_PATH = os.path.join(BASE_DIR, 'conf', 'config.yaml')
with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
cfg = yaml.safe_load(f)
table_prefix = cfg.get('table_prefix', '')
tables = cfg.get('tables', {})
metadata = MetaData()
default_mysql_opts = dict(mysql_engine='InnoDB', mysql_charset='utf8mb4')
def get_full_table_name(key):
# config.yaml에서 tables: 항목의 실제 테이블명 가져오기
name_in_cfg = tables.get(key, '')
if name_in_cfg:
# 이미 prefix 포함된 이름일 수 있으니 확인
if name_in_cfg.startswith(table_prefix):
return name_in_cfg
else:
return table_prefix + name_in_cfg
else:
# 기본은 prefix + key
return table_prefix + key
# 테이블 변수명은 prefix 제외한 key를 그대로 사용
ga4_by_date = Table(
get_full_table_name('ga4_by_date'), metadata,
Column('date', Date, primary_key=True),
Column('activeUsers', Integer),
Column('screenPageViews', Integer),
Column('sessions', Integer),
)
ga4_by_source = Table(
get_full_table_name('ga4_by_source'), metadata,
Column('date', Date, primary_key=True),
Column('sessionSource', String(255), primary_key=True),
Column('sessions', Integer),
)
ga4_by_medium = Table(
get_full_table_name('ga4_by_medium'), metadata,
Column('date', Date, primary_key=True),
Column('sessionMedium', String(255), primary_key=True),
Column('sessions', Integer),
)
ga4_by_device = Table(
get_full_table_name('ga4_by_device'), metadata,
Column('date', Date, primary_key=True),
Column('deviceCategory', String(255), primary_key=True),
Column('activeUsers', Integer),
)
ga4_by_country = Table(
get_full_table_name('ga4_by_country'), metadata,
Column('date', Date, primary_key=True),
Column('country', String(255), primary_key=True),
Column('activeUsers', Integer),
)
ga4_by_city = Table(
get_full_table_name('ga4_by_city'), metadata,
Column('date', Date, primary_key=True),
Column('city', String(255), primary_key=True),
Column('activeUsers', Integer),
)
air = Table(
get_full_table_name('air'), metadata,
Column('date', Date, primary_key=True, nullable=False),
Column('station', String(32), nullable=False),
Column('pm25', Float),
Column('pm10', Float),
Column('so2', Float),
Column('co', Float),
Column('no2', Float),
Column('o3', Float),
)
weather = Table(
get_full_table_name('weather'), metadata,
Column('date', Date, primary_key=True, nullable=False),
Column('stnId', Integer, nullable=False),
Column('avgTa', Float),
Column('minTa', Float),
Column('minTaHrmt', String(4)),
Column('maxTa', Float),
Column('maxTaHrmt', String(4)),
Column('sumRnDur', Float),
Column('mi10MaxRn', Float),
Column('mi10MaxRnHrmt', String(4)),
Column('hr1MaxRn', Float),
Column('hr1MaxRnHrmt', String(4)),
Column('sumRn', Float),
Column('maxInsWs', Float),
Column('maxInsWsWd', Integer),
Column('maxInsWsHrmt', String(4)),
Column('maxWs', Float),
Column('maxWsWd', Integer),
Column('maxWsHrmt', String(4)),
Column('avgWs', Float),
Column('hr24SumRws', Float),
Column('maxWd', Integer),
Column('avgTd', Float),
Column('minRhm', Float),
Column('minRhmHrmt', String(4)),
Column('avgRhm', Float),
Column('avgPv', Float),
Column('avgPa', Float),
Column('maxPs', Float),
Column('maxPsHrmt', String(4)),
Column('minPs', Float),
Column('minPsHrmt', String(4)),
Column('avgPs', Float),
Column('ssDur', Float),
Column('sumSsHr', Float),
Column('hr1MaxIcsrHrmt', String(4)),
Column('hr1MaxIcsr', Float),
Column('sumGsr', Float),
Column('ddMefs', Float),
Column('ddMefsHrmt', String(4)),
Column('ddMes', Float),
Column('ddMesHrmt', String(4)),
Column('sumDpthFhsc', Float),
Column('avgTca', Float),
Column('avgLmac', Float),
Column('avgTs', Float),
Column('minTg', Float),
Column('avgCm5Te', Float),
Column('avgCm10Te', Float),
Column('avgCm20Te', Float),
Column('avgCm30Te', Float),
Column('avgM05Te', Float),
Column('avgM10Te', Float),
Column('avgM15Te', Float),
Column('avgM30Te', Float),
Column('avgM50Te', Float),
Column('sumLrgEv', Float),
Column('sumSmlEv', Float),
Column('n99Rn', Float),
Column('iscs', Text),
Column('sumFogDur', Float),
)
ga4 = Table(
get_full_table_name('ga4'), metadata,
Column('date', Date, primary_key=True),
Column('source', String(255), primary_key=True),
Column('medium', String(255), primary_key=True),
Column('deviceCategory', String(50), primary_key=True),
Column('country', String(100), primary_key=True),
Column('city', String(100), primary_key=True),
Column('activeUsers', Integer),
Column('screenPageViews', Integer),
mysql_engine='InnoDB',
mysql_charset='utf8mb4'
)
holiday = Table(
get_full_table_name('holiday'), metadata,
Column('date', String(8), primary_key=True, comment='날짜 (YYYYMMDD)'),
Column('name', String(50), nullable=False, comment='휴일명'),
Column('created_at', DateTime, server_default=func.now(), comment='등록일시'),
Column('updated_at', DateTime, server_default=func.now(), onupdate=func.now(), comment='수정일시'),
comment='한국천문연구원 특일정보'
)
pos = Table(
get_full_table_name('pos'), metadata,
Column('idx', Integer, primary_key=True, autoincrement=True),
Column('date', Date, nullable=False),
Column('ca01', String(50), nullable=False),
Column('ca02', String(50), nullable=False),
Column('ca03', String(50), nullable=False),
Column('barcode', Integer, nullable=False),
Column('name', String(100), nullable=False),
Column('qty', Integer, nullable=False),
Column('tot_amount', Integer, nullable=False),
Column('tot_discount', Integer, nullable=False),
Column('actual_amount', Integer, nullable=False),
UniqueConstraint('date', 'ca01', 'ca02', 'ca03', 'name', 'barcode', name='uniq_pos_composite')
)
pos_billdata = Table(
get_full_table_name('pos_billdata'), metadata,
Column('sale_date', Date, nullable=False),
Column('shop_cd', String(20), nullable=False),
Column('pos_no', Integer, nullable=False),
Column('bill_no', Integer, nullable=False),
Column('product_cd', String(20), nullable=False),
Column('division', String(10)),
Column('table_no', String(20)),
Column('order_time', Time),
Column('pay_time', Time),
Column('barcode', String(20)),
Column('product_name', String(100)),
Column('qty', Integer),
Column('tot_sale_amt', Integer),
Column('erp_cd', String(50)),
Column('remark', Text),
Column('dc_amt', Integer),
Column('dc_type', String(50)),
Column('dcm_sale_amt', Integer),
Column('net_amt', Integer),
Column('vat_amt', Integer),
PrimaryKeyConstraint('sale_date', 'shop_cd', 'pos_no', 'bill_no', 'product_cd')
)
pos_ups_billdata = Table(
get_full_table_name('pos_ups_billdata'), metadata,
Column('sale_date', DateTime, nullable=False),
Column('shop_name', String(100), nullable=False),
Column('pos_no', String(20), nullable=False),
Column('bill_no', String(20), nullable=False),
Column('product_cd', String(20), nullable=False),
Column('ca01', String(50)),
Column('ca02', String(50)),
Column('ca03', String(50)),
Column('product_name', String(100)),
Column('barcode', String(20)),
Column('amt', Integer),
Column('qty', Integer),
Column('tot_sale_amt', Integer),
Column('dc_amt', Integer),
Column('dcm_sale_amt', Integer),
Column('net_amt', Integer),
Column('vat_amt', Integer),
Column('cash_receipt', Integer),
Column('card', Integer),
# PrimaryKeyConstraint 생략
mysql_engine='InnoDB',
mysql_charset='utf8mb4'
)
# 인덱스 추가
Index('idx_sale_shop_pos_product', pos_ups_billdata.c.sale_date, pos_ups_billdata.c.shop_name, pos_ups_billdata.c.pos_no, pos_ups_billdata.c.product_cd)
Index('idx_category', pos_ups_billdata.c.ca01, pos_ups_billdata.c.ca02, pos_ups_billdata.c.ca03)
Index('idx_product_barcode', pos_ups_billdata.c.product_name, pos_ups_billdata.c.barcode)
pos_shop_name = Table(
get_full_table_name('pos_shop_name'), metadata,
Column('shop_cd', String(20), primary_key=True, nullable=False),
Column('shop_name', String(100), nullable=False),
Column('used', Integer, nullable=False, default=1, comment='사용여부 (1=사용, 0=미사용)'),
Column('created_at', DateTime, server_default=func.current_timestamp(), comment='등록일시'),
Column('updated_at', DateTime, server_default=func.current_timestamp(), onupdate=func.current_timestamp(), comment='수정일시'),
mysql_engine='InnoDB',
mysql_charset='utf8mb4',
)