Database Migration Patterns
Overview
This guide outlines the patterns and best practices for implementing database migrations in the MOOD MNKY ecosystem. Effective migration strategies ensure that database schema changes are applied consistently across all environments without data loss or application downtime.Migration Principles
Our approach to database migrations follows these key principles:- Version control: All migrations are tracked in version control
- Forward-only: Migrations should generally only move forward, not roll back
- Incremental changes: Small, focused migrations are preferable to large schema changes
- Backward compatibility: Where possible, maintain compatibility with existing code
- Data integrity: Preserve data during schema changes
- Testing: Test migrations thoroughly before applying to production
Migration Workflow
Development Process
-
Schema Design:
- Define required schema changes in
/data/schemas/ - Update TypeScript models in
/data/models/ - Document changes in relevant READMEs
- Define required schema changes in
-
Migration Creation:
- Create a new migration file:
- The migration file will be created in
/infra/supabase/migrations/
- Create a new migration file:
-
Migration Development:
- Implement SQL commands in the migration file
- Include both schema changes and data migrations as needed
- Add comments explaining complex changes
-
Local Testing:
- Apply the migration to your local development database:
- Verify that the migration works as expected
- Test application functionality with the new schema
- Apply the migration to your local development database:
-
Commit and Review:
- Commit the migration file to version control
- Have team members review the migration
- Ensure that related application code changes are also reviewed
Deployment Process
-
Staging Deployment:
- Apply migrations to staging environment
- Run comprehensive tests against the updated schema
- Verify application functionality
-
Production Deployment:
- Schedule migration for low-traffic period if possible
- Apply migration using Supabase migration tools
- Monitor application performance after migration
- Be prepared to quickly address any issues
Migration Types
Schema Migrations
Schema migrations modify the structure of the database:Data Migrations
Data migrations modify existing data to match new schema requirements:Combined Migrations
Many migrations involve both schema and data changes:Complex Migration Patterns
Safe Column Removal
To safely remove columns:-
Step 1: Mark as deprecated in application code
- Step 2: Ensure application no longer uses the column
-
Step 3: Remove the column in a later migration
Table Renaming
To rename tables safely:-
Step 1: Create the new table
-
Step 2: Migrate data from old table
-
Step 3: Update references and remove old table in a later migration
Schema Refactoring
For major schema refactoring:- Step 1: Create new tables with the desired structure
- Step 2: Create views that match the old structure but use the new tables
- Step 3: Migrate data to the new structure
- Step 4: Switch application to use new tables
- Step 5: Remove views and old tables when no longer needed
Row Level Security (RLS) Migrations
When adding or modifying RLS policies:Function and Trigger Migrations
For database functions and triggers:Migration Best Practices
-
Use transactions: Wrap migrations in transactions to ensure atomicity
-
Include rollback commands: Add commented rollback commands as reference
-
Avoid long locks: Structure migrations to minimize table locking
-
Use IF EXISTS / IF NOT EXISTS clauses: Make migrations more robust
-
Document migrations: Add comments explaining the purpose
Handling Production Data
Special considerations for production databases:- Backup before migrating: Always have a recent backup before applying migrations
- Test with production-like data: Test migrations with a copy of production data
- Consider volume: What works quickly in development may be slow with millions of rows
- Schedule appropriately: Plan migrations during low-traffic periods
- Monitor performance: Watch for unexpected performance impacts
Supabase-Specific Patterns
Using Supabase Migrations
With Supabase, we use the Supabase CLI for migration management:Generating Types After Migration
After applying migrations, regenerate TypeScript types:Troubleshooting Migrations
Common issues and solutions:- Migration fails to apply: Check for dependencies on objects that don’t exist
- Data conversion issues: Test data migration with representative data samples
- Performance problems: Add appropriate indexes before large data migrations
- Constraint violations: Query for violating records before adding constraints