""" 解析后文件记录模型 存储上传文件解析后的每行原始数据,供已匹配列表等场景消费 """ from typing import Any, Optional from sqlalchemy import ForeignKey, Integer, String, JSON, Index from sqlalchemy.orm import Mapped, mapped_column from app.models.base import BaseModel class ParsedFileRecord(BaseModel): """ 解析后文件记录 每个上传文件解析后的一行原始数据对应一条记录 """ __tablename__ = "parsed_file_records" # 归属 company_id: Mapped[int] = mapped_column( Integer, ForeignKey("companies.id"), nullable=False, index=True ) task_id: Mapped[int] = mapped_column( Integer, ForeignKey("reconciliation_tasks.id"), nullable=False, index=True ) uploaded_file_id: Mapped[int] = mapped_column( Integer, ForeignKey("uploaded_files.id"), nullable=False, index=True ) # 数据桶/文件类型 file_bucket: Mapped[str] = mapped_column( String(30), nullable=False, default="salary", comment="数据桶: salary / social_security / tax / bank / other" ) # 行号 row_index: Mapped[int] = mapped_column(Integer, nullable=False) # 原始行数据(JSON) raw_data: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False) # 标准化后数据(JSON) normalized_data: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=True) # 员工标识(冗余存储,加速已匹配列表查询) employee_id: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, index=True) employee_name: Mapped[Optional[str]] = mapped_column(String(200), nullable=True) __table_args__ = ( Index("ix_parsed_file_records_task_bucket", "task_id", "file_bucket"), ) def __repr__(self) -> str: return ( f"" )