You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
5.1 KiB
Python

"""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")