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
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'),
|
|
) |