POTE/alembic/versions/66fd166195e8_initial_schema_officials_securities_.py
ilia 204cd0e75b Initial commit: POTE Phase 1 complete
- PR1: Project scaffold, DB models, price loader
- PR2: Congressional trade ingestion (House Stock Watcher)
- PR3: Security enrichment + deployment infrastructure
- 37 passing tests, 87%+ coverage
- Docker + Proxmox deployment ready
- Complete documentation
- Works 100% offline with fixtures
2025-12-14 20:45:34 -05:00

149 lines
7.9 KiB
Python

"""Initial schema: officials, securities, trades, prices, metrics
Revision ID: 66fd166195e8
Revises:
Create Date: 2025-12-13 22:45:47.564895
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '66fd166195e8'
down_revision: Union[str, Sequence[str], None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('officials',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=200), nullable=False),
sa.Column('chamber', sa.String(length=50), nullable=True),
sa.Column('party', sa.String(length=50), nullable=True),
sa.Column('state', sa.String(length=2), nullable=True),
sa.Column('bioguide_id', sa.String(length=20), nullable=True),
sa.Column('external_ids', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('bioguide_id')
)
op.create_index(op.f('ix_officials_name'), 'officials', ['name'], unique=False)
op.create_table('securities',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('ticker', sa.String(length=20), nullable=False),
sa.Column('name', sa.String(length=200), nullable=True),
sa.Column('exchange', sa.String(length=50), nullable=True),
sa.Column('sector', sa.String(length=100), nullable=True),
sa.Column('industry', sa.String(length=100), nullable=True),
sa.Column('asset_type', sa.String(length=50), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_securities_ticker'), 'securities', ['ticker'], unique=True)
op.create_table('metrics_official',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('official_id', sa.Integer(), nullable=False),
sa.Column('calc_date', sa.Date(), nullable=False),
sa.Column('calc_version', sa.String(length=20), nullable=False),
sa.Column('trade_count', sa.Integer(), nullable=True),
sa.Column('avg_abnormal_return_1m', sa.DECIMAL(precision=10, scale=6), nullable=True),
sa.Column('cluster_label', sa.String(length=50), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['official_id'], ['officials.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('official_id', 'calc_date', 'calc_version', name='uq_metrics_official')
)
op.create_index(op.f('ix_metrics_official_official_id'), 'metrics_official', ['official_id'], unique=False)
op.create_table('prices',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('security_id', sa.Integer(), nullable=False),
sa.Column('date', sa.Date(), nullable=False),
sa.Column('open', sa.DECIMAL(precision=15, scale=4), nullable=True),
sa.Column('high', sa.DECIMAL(precision=15, scale=4), nullable=True),
sa.Column('low', sa.DECIMAL(precision=15, scale=4), nullable=True),
sa.Column('close', sa.DECIMAL(precision=15, scale=4), nullable=False),
sa.Column('volume', sa.Integer(), nullable=True),
sa.Column('adjusted_close', sa.DECIMAL(precision=15, scale=4), nullable=True),
sa.Column('source', sa.String(length=50), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['security_id'], ['securities.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('security_id', 'date', name='uq_prices_security_date')
)
op.create_index('ix_prices_date', 'prices', ['date'], unique=False)
op.create_index(op.f('ix_prices_security_id'), 'prices', ['security_id'], unique=False)
op.create_table('trades',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('official_id', sa.Integer(), nullable=False),
sa.Column('security_id', sa.Integer(), nullable=False),
sa.Column('source', sa.String(length=50), nullable=False),
sa.Column('external_id', sa.String(length=100), nullable=True),
sa.Column('transaction_date', sa.Date(), nullable=False),
sa.Column('filing_date', sa.Date(), nullable=True),
sa.Column('side', sa.String(length=20), nullable=False),
sa.Column('value_min', sa.DECIMAL(precision=15, scale=2), nullable=True),
sa.Column('value_max', sa.DECIMAL(precision=15, scale=2), nullable=True),
sa.Column('amount', sa.DECIMAL(precision=15, scale=2), nullable=True),
sa.Column('currency', sa.String(length=3), nullable=False),
sa.Column('quality_flags', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['official_id'], ['officials.id'], ),
sa.ForeignKeyConstraint(['security_id'], ['securities.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('source', 'external_id', name='uq_trades_source_external_id')
)
op.create_index(op.f('ix_trades_filing_date'), 'trades', ['filing_date'], unique=False)
op.create_index('ix_trades_official_date', 'trades', ['official_id', 'transaction_date'], unique=False)
op.create_index(op.f('ix_trades_official_id'), 'trades', ['official_id'], unique=False)
op.create_index('ix_trades_security_date', 'trades', ['security_id', 'transaction_date'], unique=False)
op.create_index(op.f('ix_trades_security_id'), 'trades', ['security_id'], unique=False)
op.create_index(op.f('ix_trades_transaction_date'), 'trades', ['transaction_date'], unique=False)
op.create_table('metrics_trade',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('trade_id', sa.Integer(), nullable=False),
sa.Column('calc_date', sa.Date(), nullable=False),
sa.Column('calc_version', sa.String(length=20), nullable=False),
sa.Column('return_1m', sa.DECIMAL(precision=10, scale=6), nullable=True),
sa.Column('abnormal_return_1m', sa.DECIMAL(precision=10, scale=6), nullable=True),
sa.Column('signal_flags', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['trade_id'], ['trades.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('trade_id', 'calc_date', 'calc_version', name='uq_metrics_trade')
)
op.create_index(op.f('ix_metrics_trade_trade_id'), 'metrics_trade', ['trade_id'], unique=False)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_metrics_trade_trade_id'), table_name='metrics_trade')
op.drop_table('metrics_trade')
op.drop_index(op.f('ix_trades_transaction_date'), table_name='trades')
op.drop_index(op.f('ix_trades_security_id'), table_name='trades')
op.drop_index('ix_trades_security_date', table_name='trades')
op.drop_index(op.f('ix_trades_official_id'), table_name='trades')
op.drop_index('ix_trades_official_date', table_name='trades')
op.drop_index(op.f('ix_trades_filing_date'), table_name='trades')
op.drop_table('trades')
op.drop_index(op.f('ix_prices_security_id'), table_name='prices')
op.drop_index('ix_prices_date', table_name='prices')
op.drop_table('prices')
op.drop_index(op.f('ix_metrics_official_official_id'), table_name='metrics_official')
op.drop_table('metrics_official')
op.drop_index(op.f('ix_securities_ticker'), table_name='securities')
op.drop_table('securities')
op.drop_index(op.f('ix_officials_name'), table_name='officials')
op.drop_table('officials')
# ### end Alembic commands ###