models.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. """SQLAlchemy ORM models for the 拼团 (group-buy) funnel source tables.
  2. Source of truth: docs/03 §11 (v3). The MVP funnel data is split into two tables
  3. because their sync logic differs:
  4. * ``ads_trd_group_funnel_daily`` — single-day, KEEPS FULL HISTORY (daily
  5. incremental insert of a new ``dt``). Backs ``period=day``.
  6. * ``ads_trd_group_funnel_rolling`` — rolling 7d/30d, ONLY ONE ROW (daily
  7. overwrite, no history). Backs ``period=last_7d`` / ``last_30d``.
  8. Fixed funnel order (5 steps): 启动 start -> 曝光 show -> 拼团详情 detail ->
  9. 下单 order -> 成功 paid.
  10. """
  11. from __future__ import annotations
  12. from datetime import datetime
  13. from sqlalchemy import BigInteger, DateTime, String, func
  14. from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
  15. class Base(DeclarativeBase):
  16. """Declarative base for all ORM models."""
  17. class AdsTrdGroupFunnelDaily(Base):
  18. """Single-day group-buy funnel snapshot, full history (docs/03 §11.1).
  19. Daily incremental insert of a new ``dt``; any historical single day can be
  20. read back. Primary key: ``dt`` (varchar(8), yyyyMMdd).
  21. """
  22. __tablename__ = "ads_trd_group_funnel_daily"
  23. dt: Mapped[str] = mapped_column(String(8), primary_key=True)
  24. uv_start: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  25. uv_show: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  26. uv_detail: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  27. uv_order: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  28. uv_paid: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  29. etl_time: Mapped[datetime | None] = mapped_column(
  30. DateTime, nullable=True, server_default=func.now()
  31. )
  32. class AdsTrdGroupFunnelRolling(Base):
  33. """Rolling 7d/30d group-buy funnel snapshot, single row (docs/03 §11.2).
  34. Daily overwrite of the latest as-of row — no history. ``dt`` is the as-of
  35. snapshot day. Only the current rolling 7d/30d windows are available.
  36. """
  37. __tablename__ = "ads_trd_group_funnel_rolling"
  38. dt: Mapped[str] = mapped_column(String(8), primary_key=True)
  39. uv_start_7d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  40. uv_show_7d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  41. uv_detail_7d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  42. uv_order_7d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  43. uv_paid_7d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  44. uv_start_30d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  45. uv_show_30d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  46. uv_detail_30d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  47. uv_order_30d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  48. uv_paid_30d: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  49. etl_time: Mapped[datetime | None] = mapped_column(
  50. DateTime, nullable=True, server_default=func.now()
  51. )