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