| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- """add find_agent P0 gate fields
- Revision ID: 20260731_08
- Revises: 20260730_07
- Create Date: 2026-07-31
- """
- from __future__ import annotations
- from collections.abc import Sequence
- import sqlalchemy as sa
- from alembic import op
- revision: str = "20260731_08"
- down_revision: str | None = "20260731_08a"
- branch_labels: str | Sequence[str] | None = None
- depends_on: str | Sequence[str] | None = None
- def upgrade() -> None:
- inspector = sa.inspect(op.get_bind())
- run_column_names = {
- column["name"]
- for column in inspector.get_columns("video_discovery_run")
- }
- run_columns = (
- sa.Column(
- "rule_version",
- sa.String(length=64),
- nullable=True,
- comment="本次候选门禁规则版本",
- ),
- sa.Column(
- "rule_config_json",
- sa.Text(),
- nullable=True,
- comment="运行时规则、当前时间和阈值快照 JSON",
- ),
- )
- for column in run_columns:
- if column.name not in run_column_names:
- op.add_column("video_discovery_run", column)
- candidate_column_names = {
- column["name"]
- for column in inspector.get_columns("video_discovery_candidate")
- }
- columns = (
- sa.Column(
- "publish_at",
- sa.DateTime(),
- nullable=True,
- comment="视频真实发布时间,按运行时区解释",
- ),
- sa.Column(
- "duration_seconds",
- sa.Numeric(precision=10, scale=3),
- nullable=True,
- comment="视频时长(秒)",
- ),
- sa.Column(
- "content_50_plus_ratio",
- sa.Numeric(precision=8, scale=6),
- nullable=True,
- comment="视频点赞用户中 50+ 占比",
- ),
- sa.Column(
- "content_50_plus_tgi",
- sa.Numeric(precision=10, scale=4),
- nullable=True,
- comment="视频点赞用户 50+ TGI",
- ),
- sa.Column(
- "content_portrait_status",
- sa.String(length=16),
- nullable=True,
- comment="视频画像结论 pass / fail / missing",
- ),
- sa.Column(
- "account_50_plus_ratio",
- sa.Numeric(precision=8, scale=6),
- nullable=True,
- comment="账号粉丝中 50+ 占比",
- ),
- sa.Column(
- "account_50_plus_tgi",
- sa.Numeric(precision=10, scale=4),
- nullable=True,
- comment="账号粉丝 50+ TGI",
- ),
- sa.Column(
- "account_portrait_status",
- sa.String(length=16),
- nullable=True,
- comment="账号画像结论 pass / fail / missing",
- ),
- sa.Column(
- "portrait_conflict",
- sa.Integer(),
- nullable=False,
- server_default="0",
- comment="视频与账号画像结论是否冲突",
- ),
- sa.Column(
- "temporal_type",
- sa.String(length=24),
- nullable=True,
- comment="时间内容类型",
- ),
- sa.Column(
- "temporal_status",
- sa.String(length=16),
- nullable=True,
- comment="时间有效性 pass / fail / unknown",
- ),
- sa.Column(
- "temporal_evidence_json",
- sa.Text(),
- nullable=True,
- comment="时间语义、有效窗口和判断理由 JSON",
- ),
- sa.Column(
- "gate_status",
- sa.String(length=16),
- nullable=True,
- comment="硬门槛 pass / fail / pending",
- ),
- sa.Column(
- "gate_results_json",
- sa.Text(),
- nullable=True,
- comment="逐项硬门槛结果 JSON",
- ),
- sa.Column(
- "reject_reason_code",
- sa.String(length=64),
- nullable=True,
- comment="主要淘汰原因码",
- ),
- sa.Column(
- "rule_version",
- sa.String(length=64),
- nullable=True,
- comment="候选评估使用的规则版本",
- ),
- )
- for column in columns:
- if column.name not in candidate_column_names:
- op.add_column("video_discovery_candidate", column)
- def downgrade() -> None:
- inspector = sa.inspect(op.get_bind())
- candidate_column_names = {
- column["name"]
- for column in inspector.get_columns("video_discovery_candidate")
- }
- candidate_columns = (
- "rule_version",
- "reject_reason_code",
- "gate_results_json",
- "gate_status",
- "temporal_evidence_json",
- "temporal_status",
- "temporal_type",
- "portrait_conflict",
- "account_portrait_status",
- "account_50_plus_tgi",
- "account_50_plus_ratio",
- "content_portrait_status",
- "content_50_plus_tgi",
- "content_50_plus_ratio",
- "duration_seconds",
- "publish_at",
- )
- for column in candidate_columns:
- if column in candidate_column_names:
- op.drop_column("video_discovery_candidate", column)
- run_column_names = {
- column["name"]
- for column in inspector.get_columns("video_discovery_run")
- }
- if "rule_config_json" in run_column_names:
- op.drop_column("video_discovery_run", "rule_config_json")
- if "rule_version" in run_column_names:
- op.drop_column("video_discovery_run", "rule_version")
|