Configure TypeORM migrations in 5 minutes

andreasbergstrom

Andreas Bergström

Posted on October 15, 2023

Configure TypeORM migrations in 5 minutes

Database migrations are a crucial part of any robust, scalable application, allowing you to manipulate your database schema without touching the data. If you're building a NestJS application, you'll find that TypeORM is one of the most powerful tools available for this. In this blog post, we'll delve into how to manage database migrations effectively in TypeORM.

Setting Up the NestJS App Module

The first step to handling migrations in TypeORM is to set up your app.module.ts file. You can configure the TypeOrmModule to automatically run migrations when the application starts.

Here is an example:

// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigService } from '@nestjs/config';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        type: 'postgres',
        url: config.get<string>('DB_URL'),
        migrations: ['/migrations/*{.ts,.js}'],
        migrationsTableName: '_migrations',
        migrationsRun: true,  // Auto-run migrations
        entities: ['dist/**/*.entity{.ts,.js}'],
        synchronize: !!config.get<string>('DB_SYNC') || false,
        logging: true,
      }),
    }),
    // Other modules
  ],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Key Points

  • migrationsRun: true: This will run the migration files automatically when your application starts.
  • synchronize: false: This should be set to false in production as it can drop your database tables.

Install TS-Node

You will need ts-node to execute TypeScript files directly for migration purposes.

Install it as a development dependency:

npm install ts-node --save-dev
Enter fullscreen mode Exit fullscreen mode

NPM Scripts for Migrations

Add these scripts in your package.json file:

{
  "scripts": {
    "typeorm": "ts-node ./node_modules/typeorm/cli",
    "typeorm:run-migrations": "npm run typeorm migration:run -- -d ./typeOrm.config.ts",
    "typeorm:generate-migration": "npm run typeorm -- -d ./typeOrm.config.ts migration:generate ./migrations/$npm_config_name",
    "typeorm:create-migration": "npm run typeorm -- migration:create ./migrations/$npm_config_name",
    "typeorm:revert-migration": "npm run typeorm -- -d ./typeOrm.config.ts migration:revert"
  }
}
Enter fullscreen mode Exit fullscreen mode

TypeORM Configuration

Create a typeorm.config.ts file:

// typeorm.config.ts
import { DataSource } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { config } from 'dotenv';

config();

const configService = new ConfigService();

export default new DataSource({
  type: 'postgres',
  url: configService.get<string>('DB_URL'),
  entities: ['dist/**/*.entity{.ts,.js}'],
  migrations: ['dist/migrations/*.js'],
});
Enter fullscreen mode Exit fullscreen mode

The Magic of generate-migration: Auto-detecting Changes in Entities

One of the most powerful features of TypeORM is its ability to automatically detect changes in your entities and generate the appropriate migration files for you. This saves you the manual labor of writing SQL queries for each change in your entity. The generate-migration command comes in very handy for this purpose.

How It Works

The generate-migration command compares the entities in your project with your database's current state and generates a new migration file containing all the SQL queries needed to transition your database schema to match your entities.

Here's how you can use it:

npm run typeorm:generate-migration -- --name=YourMigrationName
Enter fullscreen mode Exit fullscreen mode

Replace YourMigrationName with a name that describes the changes in this migration.

Example

Suppose you have an existing User entity, and you add a new column email.

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()  // Newly added
  email: string;
}
Enter fullscreen mode Exit fullscreen mode

If you run generate-migration, TypeORM will automatically detect the new email column and generate the necessary SQL query to add this column to the user table in your database.

Important Note

Although this feature is incredibly helpful, it's not a complete substitute for understanding your database schema and migrations. It is good practice to review the generated migration files and test them in a controlled environment before applying them to your production database.

Using the NPM Scripts

Now you can use the following commands:

  • Run Migrations: \npm run typeorm:run-migrations\\
  • Generate Migrations: \npm run typeorm:generate-migration -- --name=MigrationName\\
  • Create Empty Migration: \npm run typeorm:create-migration -- --name=MigrationName\\
  • Revert Last Migration: \npm run typeorm:revert-migration\\

And that's it! You're now ready to manage your database schema changes effectively using migrations in TypeORM with a NestJS application.

Would you like to know more details about any specific part of the process? I'd be happy to clarify or go into more detail!

💖 💪 🙅 🚩
andreasbergstrom
Andreas Bergström

Posted on October 15, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related