- financial 默认增量:按 A 股披露节奏判断已最新并跳过;--full 强制全量重拉 - Tushare fina_indicator 增加报告期窗口与 100 条/请求自动分页(修复老报告期静默截断) - 新浪兜底收紧为校验兜底:两源重叠历史一致才导入缺失键,行标记 source=sina; 财务可比字段取 eps/销售毛利率(ROE 两端口径不同不作依据),日线只比较最近重叠交易日 - CLI 输出逐只进度与导入内容描述(来源/行数/报告期与公告区间),失败股票留待重跑 - financial_indicator 增 source 列(迁移 d3f6c9a21b04);新增一致性/分页/服务测试
66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
"""Alembic 迁移测试:全新数据库 upgrade head 后应包含全部 Phase 1 表。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
from pathlib import Path
|
|
|
|
from alembic import command
|
|
from alembic.config import Config
|
|
|
|
BACKEND_ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def _alembic_config(db_path: Path) -> Config:
|
|
cfg = Config(str(BACKEND_ROOT / "alembic.ini"))
|
|
cfg.set_main_option("script_location", "app/infrastructure/persistence/migrations")
|
|
cfg.set_main_option("sqlalchemy.url", f"sqlite:///{db_path}")
|
|
return cfg
|
|
|
|
|
|
def test_upgrade_head_creates_phase1_tables(tmp_path) -> None:
|
|
db_path = tmp_path / "fresh.db"
|
|
command.upgrade(_alembic_config(db_path), "head")
|
|
|
|
con = sqlite3.connect(db_path)
|
|
try:
|
|
tables = {
|
|
row[0]
|
|
for row in con.execute("select name from sqlite_master where type='table'").fetchall()
|
|
}
|
|
finally:
|
|
con.close()
|
|
|
|
expected = {
|
|
"stock",
|
|
"stock_daily",
|
|
"adjust_factor",
|
|
"trading_calendar",
|
|
"financial_indicator",
|
|
"sync_log",
|
|
"alembic_version",
|
|
}
|
|
assert expected <= tables
|
|
|
|
# 关键防未来函数列存在
|
|
con = sqlite3.connect(db_path)
|
|
try:
|
|
fin_cols = {
|
|
row[1] for row in con.execute("pragma table_info(financial_indicator)").fetchall()
|
|
}
|
|
daily_cols = {row[1] for row in con.execute("pragma table_info(stock_daily)").fetchall()}
|
|
finally:
|
|
con.close()
|
|
assert {"report_date", "announce_date"} <= fin_cols
|
|
assert {"symbol", "trade_date", "close"} <= daily_cols
|
|
# 来源标记列(新浪校验兜底行需与 Tushare 首选行区分)
|
|
assert "source" in fin_cols
|
|
assert {"source", "adjust"} <= daily_cols
|
|
|
|
|
|
def test_upgrade_head_idempotent(tmp_path) -> None:
|
|
db_path = tmp_path / "again.db"
|
|
cfg = _alembic_config(db_path)
|
|
command.upgrade(cfg, "head")
|
|
command.upgrade(cfg, "head") # 二次执行不报错
|