How handler migrations in nestjs in an effective way using typeorm

Database migrations are an essential part of modern application development, allowing developers to manage changes to their database schema in a controlled and versioned manner. When building applications with NestJS and TypeORM, handling these migrations effectively is crucial for ensuring data integrity, enabling seamless collaboration among team members, and facilitating deployments across different environments. This guide will walk you through the process of setting up and managing database migrations in your NestJS project using TypeORM, focusing on best practices for a smooth development workflow. Step 1: Download and Set Up NestJS If you don't have the NestJS CLI installed globally, begin by installing it using npm or yarn: npm install -g @nestjs/cli # or yarn global add @nestjs/cli Once the CLI is installed, create a new NestJS project: nest new project-name Navigate into your newly created project directory: cd project-name Step 2: Install Dependencies for TypeORM with NestJS You need to install the necessary packages to integrate TypeORM with your NestJS application, specifically for MySQL. This includes the @nestjs/typeorm package, typeorm itself, and the mysql2 database driver. We'll also keep reflect-metadata and typeorm-extension as they are generally useful. npm install @nestjs/typeorm typeorm mysql2 reflect-metadata typeorm-extension # or yarn add @nestjs/typeorm typeorm mysql2 reflect-metadata typeorm-extension Explanation of dependencies: @nestjs/typeorm: Provides the NestJS module for integrating TypeORM. typeorm: The core TypeORM library. mysql2: The MySQL driver. reflect-metadata: A required dependency for TypeORM to work with - TypeScript decorators. typeorm-extension: Provides helpful utilities for TypeORM, including enhanced migration capabilities. Step 3: Configure TypeORM in Your NestJS Application Now that you have the dependencies installed, the next step is to configure the TypeOrmModule in your NestJS application. We'll create a dedicated data-source.ts file at the root of your project (or in a designated configuration directory) and define your TypeORM configuration there. Create data-source.ts: Create a file named data-source.ts in the root of your project directory and add the following content: // data-source.ts import { DataSource } from 'typeorm'; import { join } from 'path'; // Import join export default new DataSource({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', // Your database username password: 'admin', // Your database password database: 'test', // Your database name entities: [ // Specify the path to your entities relative to this file join(__dirname, '**/*.entity{.ts,.js}'), ], migrations: [ // Specify the path to your migration files relative to this file join(__dirname, 'migrations/**/*{.ts,.js}'), ], migrationsRun: false, synchronize: true, // IMPORTANT: Set to false for production }); Explanation of data-source.ts: We import DataSourcefrom typeorm. We create and export a new DataSource() instance with your MySQL connection details and paths to your entities and migrations. The entitiesand migrationspaths are defined relative to the location of the data-source.ts file using join(__dirname, ...). We set migrationsRun: false to prevent migrations from running automatically on application start. Crucially, set synchronize: false for production environments. While synchronize: true can be convenient during initial development to quickly create tables based on your entities, it's dangerous in production as it can lead to data loss when schemas change. Migrations are the safe and controlled way to manage schema evolution in production. Update AppModule: Now, in your src/app.module.ts, you will import this dataSourceand use its options to configure the TypeOrmModule. import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import dataSource from './data-source'; @Module({ imports: [TypeOrmModule.forRoot({ ...dataSource.options })], controllers: [AppController], providers: [AppService], }) export class AppModule {} By using ...dataSource.options, you are spreading the configuration defined in data-source.ts into the TypeOrmModule.forRoot() method. This ensures consistency between the configuration used by your NestJS application and the TypeORM CLI. Now that your TypeORM configuration is set up using a separate data-source.ts file, you are ready to configure the TypeORM CLI and start creating your database migrations. Step 4: Configurepackage.json Scripts for Migrations To streamline the process of creating, generating, and running migrations, you should add scripts to your package.json file. These scripts will use the TypeORM CLI with the typeorm-ts-node-commonjs wrapper to execute commands directly on your T

Apr 23, 2025 - 05:02
 0
How handler migrations in nestjs in an effective way using typeorm

Database migrations are an essential part of modern application development, allowing developers to manage changes to their database schema in a controlled and versioned manner. When building applications with NestJS and TypeORM, handling these migrations effectively is crucial for ensuring data integrity, enabling seamless collaboration among team members, and facilitating deployments across different environments. This guide will walk you through the process of setting up and managing database migrations in your NestJS project using TypeORM, focusing on best practices for a smooth development workflow.

Step 1: Download and Set Up NestJS
If you don't have the NestJS CLI installed globally, begin by installing it using npm or yarn:

npm install -g @nestjs/cli
# or
yarn global add @nestjs/cli

Once the CLI is installed, create a new NestJS project:

nest new project-name

Navigate into your newly created project directory:

cd project-name

Step 2: Install Dependencies for TypeORM with NestJS
You need to install the necessary packages to integrate TypeORM with your NestJS application, specifically for MySQL. This includes the @nestjs/typeorm package, typeorm itself, and the mysql2 database driver. We'll also keep reflect-metadata and typeorm-extension as they are generally useful.

npm install @nestjs/typeorm typeorm mysql2 reflect-metadata typeorm-extension
# or
yarn add @nestjs/typeorm typeorm mysql2 reflect-metadata typeorm-extension

Explanation of dependencies:

  • @nestjs/typeorm: Provides the NestJS module for integrating TypeORM.

  • typeorm: The core TypeORM library.

  • mysql2: The MySQL driver.

  • reflect-metadata: A required dependency for TypeORM to work with - TypeScript decorators.

  • typeorm-extension: Provides helpful utilities for TypeORM, including enhanced migration capabilities.

Step 3: Configure TypeORM in Your NestJS Application

Now that you have the dependencies installed, the next step is to configure the TypeOrmModule in your NestJS application. We'll create a dedicated data-source.ts file at the root of your project (or in a designated configuration directory) and define your TypeORM configuration there.
Create data-source.ts:
Create a file named data-source.ts in the root of your project directory and add the following content:

// data-source.ts
import { DataSource } from 'typeorm';
import { join } from 'path'; // Import join

export default new DataSource({
  type: 'mysql',
  host: 'localhost',
  port: 3306,
  username: 'root', // Your database username
  password: 'admin', // Your database password
  database: 'test', // Your database name
  entities: [
    // Specify the path to your entities relative to this file
    join(__dirname, '**/*.entity{.ts,.js}'),
  ],
  migrations: [
    // Specify the path to your migration files relative to this file
    join(__dirname, 'migrations/**/*{.ts,.js}'),
  ],
  migrationsRun: false,
  synchronize: true, // IMPORTANT: Set to false for production
});

Explanation of data-source.ts:

  • We import DataSourcefrom typeorm.
  • We create and export a new DataSource() instance with your MySQL connection details and paths to your entities and migrations.
  • The entitiesand migrationspaths are defined relative to the location of the data-source.ts file using join(__dirname, ...).
  • We set migrationsRun: false to prevent migrations from running automatically on application start.
  • Crucially, set synchronize: false for production environments. While synchronize: true can be convenient during initial development to quickly create tables based on your entities, it's dangerous in production as it can lead to data loss when schemas change. Migrations are the safe and controlled way to manage schema evolution in production.

Update AppModule:

Now, in your src/app.module.ts, you will import this dataSourceand use its options to configure the TypeOrmModule.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import dataSource from './data-source';
@Module({
  imports: [TypeOrmModule.forRoot({ ...dataSource.options })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

By using ...dataSource.options, you are spreading the configuration defined in data-source.ts into the TypeOrmModule.forRoot() method. This ensures consistency between the configuration used by your NestJS application and the TypeORM CLI.

Now that your TypeORM configuration is set up using a separate data-source.ts file, you are ready to configure the TypeORM CLI and start creating your database migrations.

Step 4: Configurepackage.json Scripts for Migrations
To streamline the process of creating, generating, and running migrations, you should add scripts to your package.json file. These scripts will use the TypeORM CLI with the typeorm-ts-node-commonjs wrapper to execute commands directly on your TypeScript files, leveraging the data-source.tsconfiguration we created.

Open your package.json file and add the following scripts within the scripts block:

{
  "scripts": {
    "typeorm": "npx typeorm-ts-node-commonjs",
    "migration:create": "npm run typeorm migration:create ./src/migrations/%npm_config_name%",
    "migration:generate": "npm run typeorm migration:generate -d ./data-source.ts -n %npm_config_name%",
    "migration:run": "npm run typeorm migration:run -d ./data-source.ts",
    "migration:revert": "npm run typeorm migration:revert -d ./data-source.ts"
  },
  // ... other package.json configurations
}

Explanation of the Scripts:

  • "typeorm": "npx typeorm-ts-node-commonjs": This is a helper script that sets up the execution environment for TypeORM commands, allowing it to run TypeScript files directly. We use npx to execute the package binary without needing to install it globally.
  • "migration:create": "npm run typeorm migration:create ./src/migrations/%npm_config_name%": This script creates a new, empty migration file in the src/migrations directory. It uses %npm_config_name%to get the name you provide when running the command (e.g., npm run migration:create --name=CreateUsersTable).
  • "migration:generate": "npm run typeorm migration:generate -d ./data-source.ts -n %npm_config_name%": This script is more powerful. It generates a migration file by comparing your current database schema with your TypeORM entities. It figures out the necessary SQL commands (CREATE TABLE, ALTER TABLE, etc.) to make the database schema match your entities and writes them into a new migration file. It uses -d ./data-source.ts to specify the data source configuration and -n %npm_config_name% for the migration name.
  • "migration:run": "npm run typeorm migration:run -d ./data-source.ts": This script executes all pending migrations that have not yet been applied to the database specified in your data-source.ts.
  • "migration:revert": "npm run typeorm migration:revert -d ./data-source.ts": This script reverts the last applied migration. This is useful during development if you need to undo a recent schema change.

Difference between migration:createand migration:generate:

  • migration:create: Manual approach. Creates an empty migration file. You then manually write the up and downmethods with the SQL or TypeORM query builder commands to perform the desired schema changes.

  • migration:generate: Automatic approach. Compares entities to the database and automatically generates the SQL commands needed to synchronize the schema into the migration file's upand downmethods. You should always review the generated SQL to ensure it does exactly what you intend.