74 lines
3.4 KiB
Python
74 lines
3.4 KiB
Python
"""基地与试验地管理 —— 数据模型
|
||||
|
|
|
|||
|
|
两张无 `status` 列的域表,必须显式覆盖 `__table_args__`,
|
|||
|
|
只保留 `created_time` / `is_deleted` 索引(框架基类默认会加
|
|||
|
|
`ix_<表>_status` 索引,但本表无 status 列,不覆盖会建表失败)。
|
|||
|
|
"""
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
from sqlalchemy import Float, ForeignKey, Index, Integer, String, Text, text
|
|||
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|||
|
|
|
|||
|
|
from app.core.base_model import MappedBase, ModelMixin, UserMixin
|
|||
|
|
|
|||
|
|
|
|||
|
|
class BreedingSiteModel(ModelMixin, UserMixin, MappedBase):
|
|||
|
|
"""育种基地(试验站)主数据表。"""
|
|||
|
|
|
|||
|
|
__tablename__ = "bre_site"
|
|||
|
|
|
|||
|
|
site_name: Mapped[str] = mapped_column(
|
|||
|
|
String(100), nullable=False, unique=True, comment="基地名称"
|
|||
|
|
)
|
|||
|
|
address: Mapped[str | None] = mapped_column(String(255), nullable=True, comment="详细地址")
|
|||
|
|
area: Mapped[float | None] = mapped_column(Float, nullable=True, comment="基地面积(亩)")
|
|||
|
|
longitude: Mapped[float | None] = mapped_column(Float, nullable=True, comment="经度")
|
|||
|
|
latitude: Mapped[float | None] = mapped_column(Float, nullable=True, comment="纬度")
|
|||
|
|
eco_type: Mapped[str | None] = mapped_column(
|
|||
|
|
String(50), nullable=True, comment="生态区类型(如 华北/西北/华东/西南/东北/华南)"
|
|||
|
|
)
|
|||
|
|
soil_type: Mapped[str | None] = mapped_column(String(50), nullable=True, comment="土壤类型", default=None)
|
|||
|
|
elevation: Mapped[int | None] = mapped_column(Integer, nullable=True, comment="海拔(m)", default=None)
|
|||
|
|
remark: Mapped[str | None] = mapped_column(Text, nullable=True, comment="备注")
|
|||
|
|
|
|||
|
|
# 注:created_time / is_deleted 已由 ModelMixin 的 index=True 自动建索引
|
|||
|
|
# (ix_bre_site_created_time / ix_bre_site_is_deleted),此处仅补一个
|
|||
|
|
# 复合索引用于数据权限过滤,且必须覆盖基类默认会建的 ix_<表>_status_deleted
|
|||
|
|
# (本表无 status 列,不覆盖会引用不存在的列而建表失败)。
|
|||
|
|
__table_args__ = (
|
|||
|
|
Index("ix_bre_site_created_deleted", "created_time", "is_deleted"),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class BreedingPlotModel(ModelMixin, UserMixin, MappedBase):
|
|||
|
|
"""试验地块 —— 隶属于某个基地。"""
|
|||
|
|
|
|||
|
|
__tablename__ = "bre_plot"
|
|||
|
|
|
|||
|
|
site_id: Mapped[int] = mapped_column(
|
|||
|
|
Integer,
|
|||
|
|
ForeignKey("bre_site.id", ondelete="CASCADE"),
|
|||
|
|
nullable=False,
|
|||
|
|
index=True,
|
|||
|
|
comment="所属基地ID",
|
|||
|
|
)
|
|||
|
|
plot_code: Mapped[str] = mapped_column(
|
|||
|
|
String(50), nullable=False, comment="地块编号/名称"
|
|||
|
|
)
|
|||
|
|
row_orientation: Mapped[str | None] = mapped_column(
|
|||
|
|
String(20), nullable=True, comment="行向(南北行/东西行)"
|
|||
|
|
)
|
|||
|
|
row_count: Mapped[int | None] = mapped_column(Integer, nullable=True, comment="行数")
|
|||
|
|
col_count: Mapped[int | None] = mapped_column(Integer, nullable=True, comment="每行株数")
|
|||
|
|
grid_note: Mapped[str | None] = mapped_column(Text, nullable=True, comment="株行距/网格说明")
|
|||
|
|
area: Mapped[float | None] = mapped_column(Float, nullable=True, comment="地块面积(亩)")
|
|||
|
|
|
|||
|
|
__table_args__ = (
|
|||
|
|
Index("ix_bre_plot_created_deleted", "created_time", "is_deleted"),
|
|||
|
|
# 基地内地块编号唯一(仅约束未软删记录,与 service 层查重语义一致)
|
|||
|
|
Index(
|
|||
|
|
"uniq_bre_plot_site_code", "site_id", "plot_code",
|
|||
|
|
unique=True, postgresql_where=text("is_deleted = false"),
|
|||
|
|
),
|
|||
|
|
)
|