demand_grade.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. from __future__ import annotations
  2. from datetime import datetime
  3. from decimal import Decimal
  4. from sqlalchemy import BigInteger, Integer, Numeric, String, Text, UniqueConstraint, func
  5. from sqlalchemy.orm import Mapped, mapped_column
  6. from supply_infra.db.base import Base
  7. class DemandGrade(Base):
  8. """需求分级结果 — 对 multi_demand_pool_di 中的需求按先验/后验热度评级。"""
  9. __tablename__ = "demand_grade"
  10. __table_args__ = (UniqueConstraint("biz_dt", "demand_name", name="uk_demand_grade"),)
  11. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  12. biz_dt: Mapped[str] = mapped_column(String(32), nullable=False, comment="业务日期YYYYMMDD")
  13. demand_name: Mapped[str] = mapped_column(
  14. String(256), nullable=False, comment="需求名称(去重后的代表词)"
  15. )
  16. category_ids: Mapped[str | None] = mapped_column(
  17. Text, nullable=True, comment="归属的全局树节点id列表JSON数组(展示快照,权威关系见demand_grade_category_rel)"
  18. )
  19. grade: Mapped[str] = mapped_column(String(4), nullable=False, comment="等级 S/A/B/C/D")
  20. score: Mapped[Decimal | None] = mapped_column(
  21. Numeric(6, 2),
  22. nullable=True,
  23. comment="需求自身来源归一分0-100(来源内排名后对已有来源取均值)",
  24. )
  25. prior_total_score: Mapped[Decimal | None] = mapped_column(
  26. Numeric(16, 8), nullable=True, comment="落库时的先验 total_score 快照"
  27. )
  28. posterior_rov_avg: Mapped[Decimal | None] = mapped_column(
  29. Numeric(16, 8), nullable=True, comment="落库时的后验 rov_diff 快照(real_rov_7d_avg)"
  30. )
  31. posterior_rov_count: Mapped[int] = mapped_column(
  32. Integer, nullable=False, default=0, comment="落库时的后验样本数快照"
  33. )
  34. has_posterior: Mapped[int] = mapped_column(
  35. Integer, nullable=False, default=0, comment="是否有后验验证数据 0-无 1-有"
  36. )
  37. related_pool_ids: Mapped[str] = mapped_column(
  38. Text,
  39. nullable=False,
  40. comment="关联的原始 multi_demand_pool_di.id 列表JSON数组(必填,用于回溯原始需求)",
  41. )
  42. video_list: Mapped[str | None] = mapped_column(
  43. Text,
  44. nullable=True,
  45. comment="关联视频列表JSON(最多10个,由related_pool_ids对应原始行的video_list合并去重得到)",
  46. )
  47. strategies: Mapped[str | None] = mapped_column(
  48. Text,
  49. nullable=True,
  50. comment="来源策略列表JSON数组(由related_pool_ids对应原始行的strategy去重得到)",
  51. )
  52. reason: Mapped[str] = mapped_column(Text, nullable=False, comment="判断依据")
  53. create_time: Mapped[datetime] = mapped_column(
  54. nullable=False,
  55. server_default=func.now(),
  56. comment="创建时间",
  57. )
  58. update_time: Mapped[datetime] = mapped_column(
  59. nullable=False,
  60. server_default=func.now(),
  61. onupdate=func.now(),
  62. comment="更新时间",
  63. )