This commit is contained in:
2026-09-07 13:34:26 +08:00
parent ad9245abdd
commit 359f9ae2e4
23 changed files with 2260 additions and 513 deletions

View File

@@ -79,6 +79,163 @@ class StockBasic(Base):
delist_date: Mapped[str | None] = mapped_column(String(8))
class EtfBasic(Base):
"""场内 ETF 列表东财全市场快照ETF 同步任务维护,行情另走 candles 底座)。
ts_code 如 510300.SHsymbol 为 6 位纯数字,与 candles.symbol 同口径。
代码区间与股票不冲突:沪 51/56/58 开头、深 159 开头。
"""
__tablename__ = "etf_basic"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
ts_code: Mapped[str] = mapped_column(String(12), unique=True, index=True)
symbol: Mapped[str] = mapped_column(String(10), index=True) # 510300
name: Mapped[str] = mapped_column(String(64))
exchange: Mapped[str] = mapped_column(String(8)) # SH/SZ
list_date: Mapped[str | None] = mapped_column(String(8)) # YYYYMMDD首根K线日回填
total_mv: Mapped[float | None] = mapped_column(Float) # 总市值(元,东财快照)
circ_mv: Mapped[float | None] = mapped_column(Float) # 流通市值(元)
turnover_rate: Mapped[float | None] = mapped_column(Float) # 换手率 %
updated_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow, onupdate=_utcnow)
class StockCompany(Base):
"""上市公司基本信息tushare stock_company详情页按需单查懒加载 + 30 天新鲜度)。
行存在但 com_name 为 NULL = 负缓存墓碑tushare 无此股,避免无数据代码反复穿透)。
"""
__tablename__ = "stock_company"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
ts_code: Mapped[str] = mapped_column(String(12), unique=True, index=True) # 000001.SZ
com_name: Mapped[str | None] = mapped_column(String(255)) # 公司全称
com_id: Mapped[str | None] = mapped_column(String(32)) # 统一社会信用代码
chairman: Mapped[str | None] = mapped_column(String(128)) # 法人代表
manager: Mapped[str | None] = mapped_column(String(128)) # 总经理
secretary: Mapped[str | None] = mapped_column(String(128)) # 董秘
reg_capital: Mapped[float | None] = mapped_column(Float) # 注册资本(万元)
setup_date: Mapped[str | None] = mapped_column(String(8)) # 注册日期 YYYYMMDD
province: Mapped[str | None] = mapped_column(String(32))
city: Mapped[str | None] = mapped_column(String(32))
introduction: Mapped[str | None] = mapped_column(Text) # 公司介绍
website: Mapped[str | None] = mapped_column(String(255))
email: Mapped[str | None] = mapped_column(String(255))
office: Mapped[str | None] = mapped_column(String(255)) # 办公地址
employees: Mapped[int | None] = mapped_column(Integer) # 员工人数
main_business: Mapped[str | None] = mapped_column(Text) # 主要业务及产品
business_scope: Mapped[str | None] = mapped_column(Text) # 经营范围
updated_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow, onupdate=_utcnow)
class StockFinancial(Base):
"""个股财务数据宽表fina_indicator 指标 + 三大报表关键绝对值,按报告期一行)。
详情页懒加载,四源合并 upsert金额单位元Tushare 原始),
比率/同比为百分数。fina_indicator 列无 report_type 概念;
三大报表列只取 report_type=1合并报表
"""
__tablename__ = "stock_financial"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
ts_code: Mapped[str] = mapped_column(String(12), index=True) # 000001.SZ
end_date: Mapped[str] = mapped_column(String(8)) # 报告期 YYYYMMDD
ann_date: Mapped[str | None] = mapped_column(String(8)) # 公告日 YYYYMMDD
# ---- fina_indicatordoc 79----
eps: Mapped[float | None] = mapped_column(Float) # 基本每股收益(元)
bps: Mapped[float | None] = mapped_column(Float) # 每股净资产(元)
ocfps: Mapped[float | None] = mapped_column(Float) # 每股经营现金流净额(元)
roe: Mapped[float | None] = mapped_column(Float) # 净资产收益率 %
roe_dt: Mapped[float | None] = mapped_column(Float) # 扣非净资产收益率 %
grossprofit_margin: Mapped[float | None] = mapped_column(Float) # 销售毛利率 %
netprofit_margin: Mapped[float | None] = mapped_column(Float) # 销售净利率 %
debt_to_assets: Mapped[float | None] = mapped_column(Float) # 资产负债率 %
or_yoy: Mapped[float | None] = mapped_column(Float) # 营业收入同比 %
netprofit_yoy: Mapped[float | None] = mapped_column(Float) # 归母净利润同比 %
dt_netprofit_yoy: Mapped[float | None] = mapped_column(Float) # 扣非净利润同比 %
profit_dedt: Mapped[float | None] = mapped_column(Float) # 扣非净利润(元)
rd_exp: Mapped[float | None] = mapped_column(Float) # 研发投入(元)
# ---- incomedoc 33report_type=1----
total_revenue: Mapped[float | None] = mapped_column(Float) # 营业总收入(元)
operate_profit: Mapped[float | None] = mapped_column(Float) # 营业利润(元)
n_income_attr_p: Mapped[float | None] = mapped_column(Float) # 归母净利润(元)
# ---- balancesheetreport_type=1----
total_assets: Mapped[float | None] = mapped_column(Float) # 总资产(元)
total_hldr_eqy: Mapped[float | None] = mapped_column(Float) # 归母股东权益(元)
# ---- cashflowreport_type=1----
n_cashflow_act: Mapped[float | None] = mapped_column(Float) # 经营现金流净额(元)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow, onupdate=_utcnow)
__table_args__ = (
UniqueConstraint("ts_code", "end_date", name="uq_stock_financial_code_end"),
)
class StockDividend(Base):
"""个股分红送股tushare dividend 全历史;每 code 同步时全量替换,无唯一业务键)。
预案行div_proc != 实施)无 ex_dateK 线标记与统计只用实施行。
"""
__tablename__ = "stock_dividend"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
ts_code: Mapped[str] = mapped_column(String(12), index=True) # 000001.SZ
end_date: Mapped[str | None] = mapped_column(String(8)) # 分红年度 YYYYMMDD
ann_date: Mapped[str | None] = mapped_column(String(8)) # 预案公告日
div_proc: Mapped[str | None] = mapped_column(String(16)) # 实施进度(预案/实施)
stk_div: Mapped[float | None] = mapped_column(Float) # 每股送转
stk_bo_rate: Mapped[float | None] = mapped_column(Float) # 每股送股比例
stk_co_rate: Mapped[float | None] = mapped_column(Float) # 每股转增比例
cash_div: Mapped[float | None] = mapped_column(Float) # 每股分红(税后,元)
cash_div_tax: Mapped[float | None] = mapped_column(Float) # 每股分红(税前,元)
base_share: Mapped[float | None] = mapped_column(Float) # 基准股本(万股)
record_date: Mapped[str | None] = mapped_column(String(8)) # 股权登记日
ex_date: Mapped[str | None] = mapped_column(String(8)) # 除权除息日K线标记锚点
pay_date: Mapped[str | None] = mapped_column(String(8)) # 派息日
div_listdate: Mapped[str | None] = mapped_column(String(8)) # 红股上市日
imp_ann_date: Mapped[str | None] = mapped_column(String(8)) # 实施公告日
updated_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow, onupdate=_utcnow)
class StockSyncState(Base):
"""多行懒加载管道的同步状态(新鲜度门控 + 无数据墓碑)。
多行表无法像 stock_company 那样用「行存在但业务列 NULL」当墓碑
用本表记录每个 (ts_code, kind) 的同步时间与是否有数据。
kind: finance | dividend。
"""
__tablename__ = "stock_sync_state"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
ts_code: Mapped[str] = mapped_column(String(12), index=True)
kind: Mapped[str] = mapped_column(String(16))
last_synced_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow)
has_data: Mapped[bool] = mapped_column(Boolean, default=False)
__table_args__ = (
UniqueConstraint("ts_code", "kind", name="uq_stock_sync_code_kind"),
)
class StockReference(Base):
"""个股参考数据tushare 参考数据版块按需懒加载,一行 = 一股一分类的 JSON 快照)。
rows_json 存清洗后的 tushare 原始行数组(单位沿用各接口原始口径,见 reference.py 注册表);
行存在但 rows_json 为 NULL = 负缓存墓碑(该股该分类确认无数据)。
kind 白名单见 app/data/reference.py 的 REFERENCE_KINDS。
"""
__tablename__ = "stock_reference"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
ts_code: Mapped[str] = mapped_column(String(12), index=True) # 000001.SZ
kind: Mapped[str] = mapped_column(String(24)) # top10_holders | ...
rows_json: Mapped[str | None] = mapped_column(Text) # JSON 数组NULL=墓碑
updated_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow, onupdate=_utcnow)
__table_args__ = (
UniqueConstraint("ts_code", "kind", name="uq_stock_reference_code_kind"),
)
class MarketDaily(Base):
"""全市场未复权日线(选股专用,与回测 candles(qfq) 隔离)。