"""savings_record:真实比价上报字段 + (user_id, client_event_id) 幂等唯一约束 把 savings_record 升级为「记账唯一真相表」:真实上报(source='compare')写入 原价/比价价/支付渠道/平台包名/源平台名/源链接/幂等键/device_id; demo seeder 行(source='demo')这些列均为 NULL。 Revision ID: savings_report_fields Revises: f01db5d77dac Create Date: 2026-05-31 19:00:00.000000 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision: str = 'savings_report_fields' down_revision: Union[str, Sequence[str], None] = 'f01db5d77dac' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: with op.batch_alter_table('savings_record', schema=None) as batch_op: batch_op.add_column(sa.Column('original_price_cents', sa.Integer(), nullable=True)) batch_op.add_column(sa.Column('compared_price_cents', sa.Integer(), nullable=True)) batch_op.add_column(sa.Column('pay_channel', sa.String(length=16), nullable=True)) batch_op.add_column(sa.Column('platform_package', sa.String(length=128), nullable=True)) batch_op.add_column(sa.Column('source_platform_name', sa.String(length=32), nullable=True)) batch_op.add_column(sa.Column('source_deeplink', sa.String(length=512), nullable=True)) batch_op.add_column(sa.Column('client_event_id', sa.String(length=64), nullable=True)) batch_op.add_column(sa.Column('device_id', sa.String(length=128), nullable=True)) # (user_id, client_event_id) 幂等;demo 行 client_event_id 为 NULL 不冲突 batch_op.create_unique_constraint('uq_savings_user_event', ['user_id', 'client_event_id']) def downgrade() -> None: with op.batch_alter_table('savings_record', schema=None) as batch_op: batch_op.drop_constraint('uq_savings_user_event', type_='unique') batch_op.drop_column('device_id') batch_op.drop_column('client_event_id') batch_op.drop_column('source_deeplink') batch_op.drop_column('source_platform_name') batch_op.drop_column('platform_package') batch_op.drop_column('pay_channel') batch_op.drop_column('compared_price_cents') batch_op.drop_column('original_price_cents')