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

70 lines
3.5 KiB

"""
数据缓冲平台 - 数据模型 (SQLAlchemy ORM)
"""
from datetime import datetime
from sqlalchemy import Column, String, Integer, Float, Text, DateTime, Boolean, Index, UniqueConstraint
from app.database import Base
class MarketData(Base):
"""缓存的市场数据表"""
__tablename__ = "market_data"
id = Column(Integer, primary_key=True, autoincrement=True)
symbol = Column(String(32), nullable=False, index=True, comment="品种合约代码")
data_type = Column(String(16), nullable=False, default="futures", comment="数据类型: futures/stock")
period = Column(String(16), nullable=False, index=True, comment="周期: 5min/15min/30min/60min/daily")
# K线数据以 JSON 字符串形式存储
candles_json = Column(Text, nullable=False, comment="K线数据JSON")
current_price = Column(Float, nullable=True, comment="当前价格")
fetched_at = Column(DateTime, nullable=False, default=datetime.now, index=True, comment="获取时间")
candle_count = Column(Integer, default=0, comment="K线数量")
__table_args__ = (
UniqueConstraint("symbol", "data_type", "period", name="uq_symbol_period"),
)
def __repr__(self):
return f"<MarketData {self.symbol} {self.period} candles={self.candle_count}>"
class SymbolTimestamp(Base):
"""合约数据时间戳表 - 记录每个合约的最新数据时间"""
__tablename__ = "symbol_timestamps"
id = Column(Integer, primary_key=True, autoincrement=True)
symbol = Column(String(32), nullable=False, unique=True, index=True, comment="品种合约代码")
data_type = Column(String(16), nullable=False, default="futures", comment="数据类型")
last_refresh_at = Column(DateTime, nullable=False, default=datetime.now, comment="最后刷新时间")
refresh_count = Column(Integer, default=0, comment="刷新次数")
def __repr__(self):
return f"<SymbolTimestamp {self.symbol} last_refresh={self.last_refresh_at}>"
class ScheduledTask(Base):
"""定时任务配置表"""
__tablename__ = "scheduled_tasks"
id = Column(Integer, primary_key=True, autoincrement=True)
symbol = Column(String(32), nullable=False, comment="品种合约代码")
data_type = Column(String(16), nullable=False, default="futures", comment="数据类型")
periods = Column(String(256), nullable=False, comment="周期列表(逗号分隔), 如 5min,15min,60min")
interval_seconds = Column(Integer, nullable=False, default=300, comment="轮询间隔(秒)")
task_type = Column(String(16), nullable=False, default="interval", comment="任务类型: interval, daily, once")
run_time = Column(String(8), nullable=True, comment="执行时间,格式 HH:MM")
enabled = Column(Boolean, nullable=False, default=True, comment="是否启用")
is_finished = Column(Boolean, nullable=False, default=False, comment="是否已完成(仅一次任务执行完成后为True)")
job_id = Column(String(64), nullable=True, unique=True, comment="APScheduler job_id")
last_run = Column(DateTime, nullable=True, comment="最后执行时间")
last_status = Column(String(16), nullable=True, comment="最后状态: success/failed")
created_at = Column(DateTime, nullable=False, default=datetime.now)
updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now)
__table_args__ = (
UniqueConstraint("symbol", "data_type", name="uq_task_symbol"),
)
def __repr__(self):
return f"<Task {self.symbol} every {self.interval_seconds}s enabled={self.enabled}>"