Files
dpb/backend/app/api/v1/module_bre/dus/model.py
T

110 lines
4.8 KiB
Python
Raw Normal View History

"""DUS/品种保护 数据模型(UPOV TG/53 桃描述符模板 + 测试记录 + 观测)"""
from datetime import date
from sqlalchemy import (
JSON,
Date,
Float,
ForeignKey,
Index,
Integer,
String,
UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column
from app.core.base_model import MappedBase, ModelMixin, UserMixin
class DusDescriptorModel(ModelMixin, UserMixin, MappedBase):
"""DUS 描述符模板(§8.14UPOV TG/53 桃特性,关联 bre_trait 继承 ontology_uri)。"""
__tablename__ = "bre_dus_descriptor"
descriptor_no: Mapped[str] = mapped_column(String(32), nullable=False, unique=True, comment="描述符编号(UPOV TG/53 特性号)")
trait_id: Mapped[int | None] = mapped_column(
Integer, ForeignKey("bre_trait.id", ondelete="SET NULL"), nullable=True, comment="关联性状字典(继承 ontology_uri)", default=None
)
trait_code: Mapped[str | None] = mapped_column(String(64), nullable=True, comment="性状编码(快照)", default=None)
descriptor_name: Mapped[str] = mapped_column(String(128), nullable=False, comment="特性中文名")
expression_type: Mapped[str] = mapped_column(String(8), nullable=False, default="QN", comment="表达类型(QN数量/PQ假质量/QL质量)")
method: Mapped[str | None] = mapped_column(String(256), nullable=True, comment="测试方法(目测/测量/计数)", default=None)
example_varieties: Mapped[str | None] = mapped_column(String(512), nullable=True, comment="标准/示例品种", default=None)
test_stage: Mapped[str | None] = mapped_column(String(32), nullable=True, comment="测试生育期(苗期/花期/果熟期)", default=None)
required: Mapped[str] = mapped_column(String(1), nullable=False, default="1", comment="是否必测(1/0)")
remark: Mapped[str | None] = mapped_column(String(512), nullable=True, comment="备注", default=None)
__table_args__ = (
Index("ix_bre_dus_descriptor_created_deleted", "created_time", "is_deleted"),
)
class DusTestModel(ModelMixin, UserMixin, MappedBase):
"""DUS 测试记录(申请品种 × 测试点,含结论)。"""
__tablename__ = "bre_dus_test"
test_name: Mapped[str] = mapped_column(String(128), nullable=False, unique=True, comment="测试名称(唯一)")
germplasm_id: Mapped[int | None] = mapped_column(
Integer, ForeignKey("bre_germplasm.id", ondelete="SET NULL"), nullable=True, comment="申请/候选品种", default=None
)
trial_study_id: Mapped[int | None] = mapped_column(
Integer, ForeignKey("bre_trial_study.id", ondelete="SET NULL"), nullable=True, comment="测试点(试验研究)", default=None
)
tester: Mapped[str | None] = mapped_column(String(64), nullable=True, comment="测试人", default=None)
test_date: Mapped[date | None] = mapped_column(Date, nullable=True, comment="测试日期", default=None)
status: Mapped[str] = mapped_column(String(16), nullable=False, default="planning", comment="状态(planning/testing/completed/report)")
conclusion: Mapped[str] = mapped_column(String(32), nullable=False, default="pending", comment="结论(pending/distinct/not_distinct)")
analysis_json: Mapped[dict | None] = mapped_column(JSON, nullable=True, comment="特异性统计判定报告快照(逐描述符+建议+参照集)", default=None)
report_path: Mapped[str | None] = mapped_column(String(255), nullable=True, comment="报告附件路径", default=None)
remark: Mapped[str | None] = mapped_column(String(512), nullable=True, comment="备注", default=None)
__table_args__ = (
Index("ix_bre_dus_test_created_deleted", "created_time", "is_deleted"),
)
class DusObservationModel(ModelMixin, UserMixin, MappedBase):
"""DUS 观测(某测试 × 某描述符的表达值;数值/文本双列)。"""
__tablename__ = "bre_dus_observation"
dus_test_id: Mapped[int] = mapped_column(
Integer, ForeignKey("bre_dus_test.id", ondelete="CASCADE"), nullable=False, comment="DUS 测试"
)
dus_descriptor_id: Mapped[int] = mapped_column(
Integer, ForeignKey("bre_dus_descriptor.id", ondelete="CASCADE"), nullable=False, comment="描述符"
)
value_numeric: Mapped[float | None] = mapped_column(Float, nullable=True, comment="数值表达值", default=None)
value_text: Mapped[str | None] = mapped_column(String(256), nullable=True, comment="文本表达值", default=None)
expression_note: Mapped[str | None] = mapped_column(String(256), nullable=True, comment="表达说明", default=None)
remark: Mapped[str | None] = mapped_column(String(512), nullable=True, comment="备注", default=None)
__table_args__ = (
UniqueConstraint("dus_test_id", "dus_descriptor_id", name="uq_bre_dus_observation_test_descriptor"),
Index("ix_bre_dus_observation_created_deleted", "created_time", "is_deleted"),
)