make the migration idempotetnt
This commit is contained in:
@@ -19,49 +19,63 @@ depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
|
||||
# Create PaymentMethodType enum
|
||||
paymentmethodtype = postgresql.ENUM(
|
||||
'card', 'cash', 'bank_transfer', 'check',
|
||||
name='paymentmethodtype',
|
||||
create_type=False
|
||||
)
|
||||
paymentmethodtype.create(op.get_bind(), checkfirst=True)
|
||||
paymentmethodtype.create(conn, checkfirst=True)
|
||||
|
||||
# Add stripe_customer_id to users table
|
||||
op.add_column('users', sa.Column(
|
||||
'stripe_customer_id',
|
||||
sa.String(),
|
||||
nullable=True,
|
||||
comment='Stripe Customer ID for payment method management'
|
||||
))
|
||||
op.create_index('ix_users_stripe_customer_id', 'users', ['stripe_customer_id'])
|
||||
# Check if stripe_customer_id column exists on users table
|
||||
result = conn.execute(sa.text("""
|
||||
SELECT column_name FROM information_schema.columns
|
||||
WHERE table_name = 'users' AND column_name = 'stripe_customer_id'
|
||||
"""))
|
||||
if result.fetchone() is None:
|
||||
# Add stripe_customer_id to users table
|
||||
op.add_column('users', sa.Column(
|
||||
'stripe_customer_id',
|
||||
sa.String(),
|
||||
nullable=True,
|
||||
comment='Stripe Customer ID for payment method management'
|
||||
))
|
||||
op.create_index('ix_users_stripe_customer_id', 'users', ['stripe_customer_id'])
|
||||
|
||||
# Create payment_methods table
|
||||
op.create_table(
|
||||
'payment_methods',
|
||||
sa.Column('id', postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column('user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('users.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('stripe_payment_method_id', sa.String(), nullable=True, unique=True, comment='Stripe pm_xxx reference'),
|
||||
sa.Column('card_brand', sa.String(20), nullable=True, comment='Card brand: visa, mastercard, amex, etc.'),
|
||||
sa.Column('card_last4', sa.String(4), nullable=True, comment='Last 4 digits of card'),
|
||||
sa.Column('card_exp_month', sa.Integer(), nullable=True, comment='Card expiration month'),
|
||||
sa.Column('card_exp_year', sa.Integer(), nullable=True, comment='Card expiration year'),
|
||||
sa.Column('card_funding', sa.String(20), nullable=True, comment='Card funding type: credit, debit, prepaid'),
|
||||
sa.Column('payment_type', paymentmethodtype, nullable=False, server_default='card'),
|
||||
sa.Column('is_default', sa.Boolean(), nullable=False, server_default='false', comment='Whether this is the default payment method for auto-renewals'),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False, server_default='true', comment='Soft delete flag - False means removed'),
|
||||
sa.Column('is_manual', sa.Boolean(), nullable=False, server_default='false', comment='True for manually recorded methods (cash/check)'),
|
||||
sa.Column('manual_notes', sa.Text(), nullable=True, comment='Admin notes for manual payment methods'),
|
||||
sa.Column('created_by', postgresql.UUID(as_uuid=True), sa.ForeignKey('users.id', ondelete='SET NULL'), nullable=True, comment='Admin who added this on behalf of user'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now(), onupdate=sa.func.now()),
|
||||
)
|
||||
# Check if payment_methods table exists
|
||||
result = conn.execute(sa.text("""
|
||||
SELECT table_name FROM information_schema.tables
|
||||
WHERE table_name = 'payment_methods'
|
||||
"""))
|
||||
if result.fetchone() is None:
|
||||
# Create payment_methods table
|
||||
op.create_table(
|
||||
'payment_methods',
|
||||
sa.Column('id', postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column('user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('users.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('stripe_payment_method_id', sa.String(), nullable=True, unique=True, comment='Stripe pm_xxx reference'),
|
||||
sa.Column('card_brand', sa.String(20), nullable=True, comment='Card brand: visa, mastercard, amex, etc.'),
|
||||
sa.Column('card_last4', sa.String(4), nullable=True, comment='Last 4 digits of card'),
|
||||
sa.Column('card_exp_month', sa.Integer(), nullable=True, comment='Card expiration month'),
|
||||
sa.Column('card_exp_year', sa.Integer(), nullable=True, comment='Card expiration year'),
|
||||
sa.Column('card_funding', sa.String(20), nullable=True, comment='Card funding type: credit, debit, prepaid'),
|
||||
sa.Column('payment_type', paymentmethodtype, nullable=False, server_default='card'),
|
||||
sa.Column('is_default', sa.Boolean(), nullable=False, server_default='false', comment='Whether this is the default payment method for auto-renewals'),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False, server_default='true', comment='Soft delete flag - False means removed'),
|
||||
sa.Column('is_manual', sa.Boolean(), nullable=False, server_default='false', comment='True for manually recorded methods (cash/check)'),
|
||||
sa.Column('manual_notes', sa.Text(), nullable=True, comment='Admin notes for manual payment methods'),
|
||||
sa.Column('created_by', postgresql.UUID(as_uuid=True), sa.ForeignKey('users.id', ondelete='SET NULL'), nullable=True, comment='Admin who added this on behalf of user'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now(), onupdate=sa.func.now()),
|
||||
)
|
||||
|
||||
# Create indexes
|
||||
op.create_index('ix_payment_methods_user_id', 'payment_methods', ['user_id'])
|
||||
op.create_index('ix_payment_methods_stripe_pm_id', 'payment_methods', ['stripe_payment_method_id'])
|
||||
op.create_index('idx_payment_method_user_default', 'payment_methods', ['user_id', 'is_default'])
|
||||
op.create_index('idx_payment_method_active', 'payment_methods', ['user_id', 'is_active'])
|
||||
# Create indexes
|
||||
op.create_index('ix_payment_methods_user_id', 'payment_methods', ['user_id'])
|
||||
op.create_index('ix_payment_methods_stripe_pm_id', 'payment_methods', ['stripe_payment_method_id'])
|
||||
op.create_index('idx_payment_method_user_default', 'payment_methods', ['user_id', 'is_default'])
|
||||
op.create_index('idx_payment_method_active', 'payment_methods', ['user_id', 'is_active'])
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
Reference in New Issue
Block a user