""" 报告持久化模块。 将 CLI 脚本输出的 Markdown 报告存入 DB(mac_report 表)。 同一日期+研究对象的新报告入库时,旧报告自动标记为失效(is_active=0)。 """ from datetime import datetime from sqlalchemy import text from database.connection import get_engine from database.models import Report, create_all_tables def save_report( content: str, title: str, report_date: str | None = None, subject_type: str = "daily", subject_code: str = "", ) -> int: """ 保存报告到 DB。 如果同一天、同一研究对象已有报告,先将其标记为 is_active=0, 然后插入新报告。 参数: content: Markdown 报告内容 title: 报告标题 report_date: 报告日期 YYYYMMDD,默认今天 subject_type: 研究对象类型 (stock/index/sector/portfolio/daily) subject_code: 研究对象代码 (如 000001.SZ 或 000300.SH) 返回: 新报告的 id """ report_date = report_date or datetime.now().strftime("%Y%m%d") engine = get_engine() # 确保表存在 create_all_tables() # 将同日期+同对象的旧报告标记失效 with engine.connect() as conn: conn.execute( text( "UPDATE {} SET is_active = 0 " "WHERE report_date = :d AND subject_type = :st AND subject_code = :sc AND is_active = 1" .format(Report.__tablename__) ), {"d": report_date, "st": subject_type, "sc": subject_code}, ) conn.commit() # 插入新报告 report = Report( report_date=report_date, title=title, subject_type=subject_type, subject_code=subject_code, content=content, created_at=datetime.now(), is_active=1.0, ) from sqlalchemy.orm import Session with Session(engine) as session: session.add(report) session.commit() report_id = report.id session.expunge_all() return report_id def query_reports( report_date: str | None = None, subject_type: str | None = None, subject_code: str | None = None, active_only: bool = True, limit: int = 20, ) -> list[dict]: """查询报告列表。""" engine = get_engine() table = Report.__tablename__ sql = "SELECT * FROM {} WHERE 1=1".format(table) params = {} if report_date: sql += " AND report_date = :d" params["d"] = report_date if subject_type: sql += " AND subject_type = :st" params["st"] = subject_type if subject_code: sql += " AND subject_code = :sc" params["sc"] = subject_code if active_only: sql += " AND is_active = 1" sql += " ORDER BY id DESC LIMIT :lim" params["lim"] = limit with engine.connect() as conn: rows = conn.execute(text(sql), params).fetchall() result = [] for r in rows: d = dict(r._mapping) # DATE/DATETIME 列 → 字符串 for key in ("report_date", "created_at"): val = d.get(key) if hasattr(val, "strftime"): fmt = "%Y%m%d" if key == "report_date" else "%Y-%m-%d %H:%M:%S" d[key] = val.strftime(fmt) result.append(d) return result