You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.7 KiB
Python

"""
FRED (Federal Reserve Economic Data) database models
"""
from sqlalchemy import Column, Integer, String, Text, DateTime, Float, Index, Boolean
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.sql import func
from app.core.database import Base
class FredSeries(Base):
"""FRED 시리즈 메타데이터 저장"""
__tablename__ = "fred_series"
id = Column(String(50), primary_key=True) # Series ID (e.g., "GDP")
title = Column(Text, nullable=False)
units = Column(String(100))
units_short = Column(String(50))
frequency = Column(String(20)) # Annual, Quarterly, Monthly, etc.
frequency_short = Column(String(10))
seasonal_adjustment = Column(String(50))
seasonal_adjustment_short = Column(String(10))
last_updated = Column(DateTime)
popularity = Column(Integer, default=0)
group_popularity = Column(Integer, default=0)
notes = Column(Text)
# Cache metadata
cached_at = Column(DateTime, default=func.now())
cache_expires_at = Column(DateTime)
# API response metadata
fred_metadata = Column(JSONB, nullable=True) # Store full FRED response
__table_args__ = (
Index('idx_fred_series_title', 'title'),
Index('idx_fred_series_frequency', 'frequency'),
Index('idx_fred_series_cached_at', 'cached_at'),
)
class FredObservation(Base):
"""FRED 시리즈 관측값 저장"""
__tablename__ = "fred_observations"
id = Column(Integer, primary_key=True, autoincrement=True)
series_id = Column(String(50), nullable=False, index=True)
date = Column(String(20), nullable=False) # YYYY-MM-DD format
value = Column(String(20)) # String to handle "." for missing values
realtime_start = Column(String(20))
realtime_end = Column(String(20))
# Cache metadata
cached_at = Column(DateTime, default=func.now())
__table_args__ = (
Index('idx_fred_obs_series_date', 'series_id', 'date'),
Index('idx_fred_obs_cached_at', 'cached_at'),
)
class FredApiUsage(Base):
"""FRED API 사용량 추적 (일일 1000개 제한 관리)"""
__tablename__ = "fred_api_usage"
id = Column(Integer, primary_key=True, autoincrement=True)
date = Column(String(10), nullable=False, index=True) # YYYY-MM-DD
endpoint = Column(String(50), nullable=False) # 'series', 'observations', etc.
series_id = Column(String(50))
request_params = Column(JSONB) # Store request parameters
success = Column(Boolean, default=True)
response_size = Column(Integer) # Number of records returned
created_at = Column(DateTime, default=func.now())
__table_args__ = (
Index('idx_fred_usage_date', 'date'),
Index('idx_fred_usage_endpoint', 'endpoint'),
Index('idx_fred_usage_date_endpoint', 'date', 'endpoint'),
)
class FredCacheStats(Base):
"""FRED 캐시 통계 및 성능 메트릭"""
__tablename__ = "fred_cache_stats"
id = Column(Integer, primary_key=True, autoincrement=True)
date = Column(String(10), nullable=False, index=True) # YYYY-MM-DD
# API usage stats
total_requests = Column(Integer, default=0)
api_calls_made = Column(Integer, default=0)
cache_hits = Column(Integer, default=0)
cache_hit_rate = Column(Float) # Percentage
# Data stats
total_series_cached = Column(Integer, default=0)
total_observations_cached = Column(Integer, default=0)
cache_size_mb = Column(Float)
# Performance stats
avg_response_time_ms = Column(Float)
api_limit_usage_pct = Column(Float) # Percentage of 1000 daily limit used
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
__table_args__ = (
Index('idx_fred_stats_date', 'date'),
)