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