39 lines
1.5 KiB
Python
39 lines
1.5 KiB
Python
|
|
"""Preserve independent stock detail facts without invalidating old publications."""
|
||
|
|
|
||
|
|
from collections.abc import Sequence
|
||
|
|
|
||
|
|
import sqlalchemy as sa
|
||
|
|
from alembic import op
|
||
|
|
|
||
|
|
revision: str = "0008_radar_detail"
|
||
|
|
down_revision: str | None = "0007_selection_pattern_scoring"
|
||
|
|
branch_labels: str | Sequence[str] | None = None
|
||
|
|
depends_on: str | Sequence[str] | None = None
|
||
|
|
|
||
|
|
|
||
|
|
def upgrade() -> None:
|
||
|
|
"""Add nullable facts and allow the optional raw moneyflow checkpoint."""
|
||
|
|
for name in ("pct_change", "active_buy_net_amount_yuan"):
|
||
|
|
op.add_column("sector_radar_stock_fact", sa.Column(name, sa.Numeric(), nullable=True))
|
||
|
|
op.create_check_constraint(
|
||
|
|
f"ck_radar_stock_{name}_finite",
|
||
|
|
"sector_radar_stock_fact",
|
||
|
|
f"{name} IS NULL OR {name} NOT IN "
|
||
|
|
"('NaN'::numeric, 'Infinity'::numeric, '-Infinity'::numeric)",
|
||
|
|
)
|
||
|
|
op.drop_constraint(
|
||
|
|
"ck_sector_radar_publication_source_group", "sector_radar_publication_source"
|
||
|
|
)
|
||
|
|
op.create_check_constraint(
|
||
|
|
"ck_sector_radar_publication_source_group",
|
||
|
|
"sector_radar_publication_source",
|
||
|
|
"source_group IN ('calendar', 'concept_indices', 'industry_indices', 'members', "
|
||
|
|
"'stock_basics', 'suspensions', 'daily', 'moneyflow_dc', 'moneyflow')",
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def downgrade() -> None:
|
||
|
|
"""Drop added fact columns; retain optional checkpoint audit rows for older readers."""
|
||
|
|
for name in ("pct_change", "active_buy_net_amount_yuan"):
|
||
|
|
op.drop_column("sector_radar_stock_fact", name)
|