Migration Guidelines
Database migrations are version-controlled scripts that manage changes to your database schema and data over time. They ensure that all environments (development, staging, production) maintain consistent database structure and allow for safe, repeatable deployments.
In OWOX Data Marts, migrations handle:
- Creating, altering, or dropping database tables and columns
- Modifying indexes and constraints
- Data transformation during schema changes
- Ensuring compatibility across MySQL and SQLite databases
General Principles
Section titled âGeneral Principlesâ- The TypeORM
synchronizeoption must be set tofalse. This is required to prevent data loss and uncontrolled schema changes. - All schema changes (creating, altering, or dropping tables and columns) must be implemented via migrations.
- For schema (DDL) changes, use the declarative migration style (e.g., via
Table,TableColumn, etc.) to ensure compatibility with both MySQL and SQLite. - For data (DML) changes, use SQL queries (
queryRunner.query). Minimize their use and ensure all queries are cross-database compatible. - All migrations must be compatible with both MySQL and SQLite.
- All migration files are located in the
/src/migrationsdirectory and must be named with a leading timestamp(e.g.,1680000000000-add-user-table.ts). - Migrations can be executed automatically on NestJS application startup if the
environment variable
RUN_MIGRATIONSis set totrue.
Development Workflow
Section titled âDevelopment WorkflowâImportant: All npm scripts must be executed from the monorepo root directory. These scripts internally use OWOX CLI, so both
owoxandbackendpackages must be built before working with migrations.
Creating a Migration Template
Section titled âCreating a Migration TemplateâTo generate a migration template, use the following command:
npm run migrations:create-template <MigrationName>Where <MigrationName> is the desired name for your migration (e.g.,
add-user-table).
Working with Migrations
Section titled âWorking with Migrationsâ-
To check migrations status:
Terminal window npm run migrations:status -
To run all pending migrations:
Terminal window npm run migrations:up -
To revert the last executed migration:
Terminal window npm run migrations:down
Migration Examples
Section titled âMigration ExamplesâDeclarative Migration (DDL)
Section titled âDeclarative Migration (DDL)âimport { MigrationInterface, QueryRunner, Table } from 'typeorm';
export class AddUserTable1680000000000 implements MigrationInterface { async up(queryRunner: QueryRunner): Promise<void> { await queryRunner.createTable( new Table({ name: 'user', columns: [ { name: 'id', type: 'int', isPrimary: true, isGenerated: true, generationStrategy: 'increment', }, { name: 'name', type: 'varchar' }, ], }) ); }
async down(queryRunner: QueryRunner): Promise<void> { await queryRunner.dropTable('user'); }}Data Migration (DML)
Section titled âData Migration (DML)âawait queryRunner.query("UPDATE table_name SET status = 'run' WHERE status = 'active'");Note: Write DML queries to be compatible with both MySQL and SQLite.
Best Practices
Section titled âBest PracticesâNaming Conventions
Section titled âNaming Conventionsâ- Use descriptive names in kebab-case:
add-user-email-indexinstead ofupdate-user - Include timestamp prefix for proper ordering
- File names use kebab-case, but class names use PascalCase
Safe Migration Patterns
Section titled âSafe Migration Patternsâ- Always implement both
up()anddown()methods - Test migrations on sample data before production
- Make backward-compatible changes when possible
- Use transactions for multi-step operations
Database Compatibility
Section titled âDatabase CompatibilityâOWOX Data Marts supports both MySQL and SQLite. When writing migrations:
Supported Column Types
Section titled âSupported Column TypesâUse TypeORMâs standard types that map correctly to both databases:
varchar,textfor stringsint,bigintfor integersdecimalfor precise numbersdatetimefor timestampsbooleanfor flags
Cross-Database Guidelines
Section titled âCross-Database Guidelinesâ- Use TypeORMâs declarative API instead of raw SQL when possible
- Test migrations on both MySQL and SQLite
- Avoid database-specific features in column types
- Use standard SQL for data migrations
- Avoid database-specific functions in DML queries
- Avoid specific index types or constraints