| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- """create the complete video discovery persistence tables
- Revision ID: 20260731_08a
- Revises: 20260730_07
- Create Date: 2026-07-31
- The tables predate Alembic and were previously installed from files under
- ``sql/``. ``checkfirst``-style inspection keeps this migration safe for
- databases where those legacy DDL files were already applied, while making a
- fresh ``alembic upgrade head`` self-contained.
- """
- from __future__ import annotations
- from collections.abc import Sequence
- import sqlalchemy as sa
- from alembic import op
- revision: str = "20260731_08a"
- down_revision: str | None = "20260730_07"
- branch_labels: str | Sequence[str] | None = None
- depends_on: str | Sequence[str] | None = None
- def _table_names() -> set[str]:
- return set(sa.inspect(op.get_bind()).get_table_names())
- def _create_run_table() -> None:
- op.create_table(
- "video_discovery_run",
- sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
- sa.Column("run_id", sa.String(length=64), nullable=False, comment="Agent 运行标识"),
- sa.Column("biz_dt", sa.String(length=32), nullable=True, comment="业务日 YYYYMMDD"),
- sa.Column("demand_grade_id", sa.BigInteger(), nullable=True),
- sa.Column("demand_word", sa.String(length=256), nullable=False),
- sa.Column("seed_video_id", sa.String(length=64), nullable=True),
- sa.Column("seed_video_title", sa.String(length=512), nullable=True),
- sa.Column("relevant_points_json", sa.Text(), nullable=False),
- sa.Column("intent_summary", sa.Text(), nullable=True),
- sa.Column(
- "status",
- sa.String(length=24),
- nullable=False,
- server_default="running",
- ),
- sa.Column("search_count", sa.Integer(), nullable=False, server_default="0"),
- sa.Column("primary_count", sa.Integer(), nullable=False, server_default="0"),
- sa.Column("stop_reason", sa.Text(), nullable=True),
- sa.Column(
- "create_time",
- sa.DateTime(),
- nullable=False,
- server_default=sa.func.now(),
- ),
- sa.Column(
- "update_time",
- sa.DateTime(),
- nullable=False,
- server_default=sa.func.now(),
- ),
- sa.PrimaryKeyConstraint("id"),
- sa.UniqueConstraint("run_id", name="uk_video_discovery_run_id"),
- sa.UniqueConstraint(
- "biz_dt",
- "demand_grade_id",
- name="uk_video_discovery_run_biz_grade",
- ),
- mysql_charset="utf8mb4",
- )
- op.create_index(
- "idx_video_discovery_run_demand",
- "video_discovery_run",
- ["demand_word"],
- )
- op.create_index(
- "idx_video_discovery_run_grade",
- "video_discovery_run",
- ["demand_grade_id"],
- )
- op.create_index(
- "idx_video_discovery_run_biz_dt",
- "video_discovery_run",
- ["biz_dt"],
- )
- op.create_index(
- "idx_video_discovery_run_status",
- "video_discovery_run",
- ["status"],
- )
- def _create_search_table() -> None:
- op.create_table(
- "video_discovery_search",
- sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
- sa.Column("run_id", sa.String(length=64), nullable=False),
- sa.Column("search_key", sa.String(length=64), nullable=False),
- sa.Column("keyword", sa.String(length=256), nullable=False),
- sa.Column("query_reason", sa.Text(), nullable=False),
- sa.Column("source_type", sa.String(length=32), nullable=False),
- sa.Column("source_value", sa.Text(), nullable=True),
- sa.Column("parent_search_id", sa.BigInteger(), nullable=True),
- sa.Column(
- "provider",
- sa.String(length=32),
- nullable=False,
- server_default="internal_keyword",
- ),
- sa.Column("provider_state_json", sa.Text(), nullable=True),
- sa.Column(
- "content_type",
- sa.String(length=16),
- nullable=False,
- server_default="视频",
- ),
- sa.Column(
- "sort_type",
- sa.String(length=32),
- nullable=False,
- server_default="综合排序",
- ),
- sa.Column(
- "publish_time",
- sa.String(length=32),
- nullable=False,
- server_default="不限",
- ),
- sa.Column(
- "cursor",
- sa.String(length=128),
- nullable=False,
- server_default="0",
- ),
- sa.Column("page_no", sa.Integer(), nullable=False, server_default="1"),
- sa.Column("results_count", sa.Integer(), nullable=False, server_default="0"),
- sa.Column(
- "new_candidate_count",
- sa.Integer(),
- nullable=False,
- server_default="0",
- ),
- sa.Column("has_more", sa.Integer(), nullable=False, server_default="0"),
- sa.Column("next_cursor", sa.String(length=128), nullable=True),
- sa.Column("result_ids_json", sa.Text(), nullable=True),
- sa.Column(
- "status",
- sa.String(length=16),
- nullable=False,
- server_default="success",
- ),
- sa.Column("error_message", sa.Text(), nullable=True),
- sa.Column(
- "create_time",
- sa.DateTime(),
- nullable=False,
- server_default=sa.func.now(),
- ),
- sa.Column(
- "update_time",
- sa.DateTime(),
- nullable=False,
- server_default=sa.func.now(),
- ),
- sa.PrimaryKeyConstraint("id"),
- mysql_charset="utf8mb4",
- )
- op.create_index(
- "idx_video_discovery_search_run",
- "video_discovery_search",
- ["run_id", "id"],
- )
- op.create_index(
- "idx_video_discovery_search_parent",
- "video_discovery_search",
- ["run_id", "parent_search_id"],
- )
- op.create_index(
- "idx_video_discovery_search_keyword",
- "video_discovery_search",
- ["keyword"],
- )
- def _create_candidate_table() -> None:
- op.create_table(
- "video_discovery_candidate",
- sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
- sa.Column("run_id", sa.String(length=64), nullable=False),
- sa.Column(
- "search_id",
- sa.BigInteger(),
- sa.ForeignKey(
- "video_discovery_search.id",
- name="fk_video_discovery_candidate_search",
- ondelete="RESTRICT",
- ),
- nullable=True,
- ),
- sa.Column("aweme_id", sa.String(length=64), nullable=False),
- sa.Column("title", sa.String(length=512), nullable=True),
- sa.Column("content_link", sa.String(length=1024), nullable=True),
- sa.Column("author_name", sa.String(length=256), nullable=True),
- sa.Column("author_sec_uid", sa.String(length=256), nullable=True),
- sa.Column("source_keywords_json", sa.Text(), nullable=True),
- sa.Column("source_search_ids_json", sa.Text(), nullable=True),
- sa.Column("tags_json", sa.Text(), nullable=True),
- sa.Column("play_count", sa.BigInteger(), nullable=True),
- sa.Column("like_count", sa.BigInteger(), nullable=True),
- sa.Column("comment_count", sa.BigInteger(), nullable=True),
- sa.Column("collect_count", sa.BigInteger(), nullable=True),
- sa.Column("share_count", sa.BigInteger(), nullable=True),
- sa.Column("content_age_evidence_json", sa.Text(), nullable=True),
- sa.Column("account_age_evidence_json", sa.Text(), nullable=True),
- sa.Column("age_normalization_json", sa.Text(), nullable=True),
- sa.Column("relevance_score", sa.Numeric(8, 6), nullable=True),
- sa.Column("elder_score", sa.Numeric(8, 6), nullable=True),
- sa.Column("share_score", sa.Numeric(8, 6), nullable=True),
- sa.Column("value_score", sa.Numeric(8, 2), nullable=True),
- sa.Column("decision_reason", sa.Text(), nullable=True),
- sa.Column(
- "decision_bucket",
- sa.String(length=24),
- nullable=False,
- server_default="pending_evaluation",
- ),
- sa.Column("aigc_crawler_plan_id", sa.String(length=64), nullable=True),
- sa.Column("aigc_produce_plan_id", sa.String(length=64), nullable=True),
- sa.Column("aigc_publish_plan_id", sa.String(length=64), nullable=True),
- sa.Column("aigc_plan_label", sa.String(length=64), nullable=True),
- sa.Column(
- "create_time",
- sa.DateTime(),
- nullable=False,
- server_default=sa.func.now(),
- ),
- sa.Column(
- "update_time",
- sa.DateTime(),
- nullable=False,
- server_default=sa.func.now(),
- ),
- sa.PrimaryKeyConstraint("id"),
- mysql_charset="utf8mb4",
- )
- op.create_index(
- "idx_video_discovery_candidate_search",
- "video_discovery_candidate",
- ["search_id", "id"],
- )
- op.create_index(
- "idx_video_discovery_candidate_bucket",
- "video_discovery_candidate",
- ["run_id", "decision_bucket"],
- )
- op.create_index(
- "idx_video_discovery_candidate_author",
- "video_discovery_candidate",
- ["author_sec_uid"],
- )
- def upgrade() -> None:
- tables = _table_names()
- if "video_discovery_run" not in tables:
- _create_run_table()
- if "video_discovery_search" not in tables:
- _create_search_table()
- if "video_discovery_candidate" not in tables:
- _create_candidate_table()
- def downgrade() -> None:
- # These tables may have existed before Alembic took ownership of the schema.
- # A destructive automatic downgrade could delete legacy production data, so
- # this adoption migration is intentionally forward-only.
- pass
|