"""add attention subsystem tables Revision ID: a1b2c3d4e5f6 Revises: 5c3d0565afcc Create Date: 2026-03-17 Adds four tables for the event-centric attention subsystem: - company_entity_map - wiki_pageviews_daily - gdelt_article_raw - attention_features_daily """ from typing import Sequence, Union import sqlalchemy as sa from alembic import op from sqlalchemy.dialects import postgresql revision: str = "a1b2c3d4e5f6" down_revision: Union[str, Sequence[str], None] = "5c3d0565afcc" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: conn = op.get_bind() # company_entity_map if not conn.dialect.has_table(conn, "company_entity_map"): op.create_table( "company_entity_map", sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True), sa.Column("ticker", sa.String(10), nullable=False), sa.Column("canonical_name", sa.String(500), nullable=False), sa.Column("wiki_title", sa.String(500), nullable=True), sa.Column("gdelt_query", sa.String(1000), nullable=True), sa.Column("aliases_json", postgresql.JSON(astext_type=sa.Text()), nullable=True), sa.Column("resolver_confidence", sa.Float(), nullable=True), sa.Column("is_manual_override", sa.Boolean(), nullable=True), sa.Column("created_at", postgresql.TIMESTAMP(timezone=True), nullable=True), sa.Column("updated_at", postgresql.TIMESTAMP(timezone=True), nullable=True), sa.UniqueConstraint("ticker", name="company_entity_map_ticker_key"), sa.PrimaryKeyConstraint("id"), ) op.create_index("idx_company_entity_map_ticker", "company_entity_map", ["ticker"]) # wiki_pageviews_daily if not conn.dialect.has_table(conn, "wiki_pageviews_daily"): op.create_table( "wiki_pageviews_daily", sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True), sa.Column("wiki_title", sa.String(500), nullable=False), sa.Column("date", sa.Date(), nullable=False), sa.Column("views", sa.Integer(), nullable=False), sa.Column("created_at", postgresql.TIMESTAMP(timezone=True), nullable=True), sa.UniqueConstraint("wiki_title", "date", name="uq_wiki_pageviews_daily"), sa.PrimaryKeyConstraint("id"), ) op.create_index("idx_wiki_pageviews_daily_title_date", "wiki_pageviews_daily", ["wiki_title", "date"]) # gdelt_article_raw if not conn.dialect.has_table(conn, "gdelt_article_raw"): op.create_table( "gdelt_article_raw", sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True), sa.Column("url", sa.String(2000), nullable=False), sa.Column("title", sa.Text(), nullable=True), sa.Column("domain", sa.String(255), nullable=True), sa.Column("published_at", postgresql.TIMESTAMP(timezone=True), nullable=True), sa.Column("sourcecountry", sa.String(10), nullable=True), sa.Column("matched_ticker", sa.String(10), nullable=False), sa.Column("match_method", sa.String(50), nullable=True), sa.Column("match_confidence", sa.Float(), nullable=True), sa.Column("created_at", postgresql.TIMESTAMP(timezone=True), nullable=True), sa.UniqueConstraint("url", name="gdelt_article_raw_url_key"), sa.PrimaryKeyConstraint("id"), ) op.create_index("idx_gdelt_article_raw_ticker", "gdelt_article_raw", ["matched_ticker"]) op.create_index("idx_gdelt_article_raw_published_at", "gdelt_article_raw", ["published_at"]) # attention_features_daily if not conn.dialect.has_table(conn, "attention_features_daily"): op.create_table( "attention_features_daily", sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True), sa.Column("ticker", sa.String(10), nullable=False), sa.Column("date", sa.Date(), nullable=False), sa.Column("wiki_views", sa.Integer(), nullable=True), sa.Column("wiki_spike_10d", sa.Float(), nullable=True), sa.Column("wiki_zscore_20d", sa.Float(), nullable=True), sa.Column("gdelt_article_count_1d", sa.Integer(), nullable=True), sa.Column("gdelt_article_count_3d", sa.Integer(), nullable=True), sa.Column("gdelt_unique_domains_3d", sa.Integer(), nullable=True), sa.Column("gdelt_us_article_count_3d", sa.Integer(), nullable=True), sa.Column("created_at", postgresql.TIMESTAMP(timezone=True), nullable=True), sa.UniqueConstraint("ticker", "date", name="uq_attention_features_daily"), sa.PrimaryKeyConstraint("id"), ) op.create_index("idx_attention_features_daily_ticker_date", "attention_features_daily", ["ticker", "date"]) def downgrade() -> None: op.drop_table("attention_features_daily") op.drop_table("gdelt_article_raw") op.drop_table("wiki_pageviews_daily") op.drop_table("company_entity_map")