How to create and generate migrations in Typeorm 0.3+ with NestJS 9+
Tags: nestjs, typescript, typeorm
Published: 2023-10-10 06:17:34

Migration from Typeorm 0.2 to 0.3 has made changes in how to connect to the database and run migrations due to the fact that they deprecated ormconfig.json but you have to use dataSource which will hold the database connection.

so today I'll show you how to write generate and run migrations in NestJS 9+ with Typeorm 0.3+ with sample code.

First of all install the latest version of nestjs-cli, ts-node,  typeorm, and your database like Postgres, MySQL with the following commands
```
$ npm i -g @nestjs/cli 
$ npm i -g typeorm
$ npm i -g ts-node
```

Create a project or in your existing project configure database connections and create entities for your database.

Let's get started by creating a dataSource.ts file in your project
 dataSource.ts

```
import * as dotenv from 'dotenv';
dotenv.config();
import { DataSource } from 'typeorm';

export default new DataSource({
  type: 'postgres',
  host: process.env.DATABASE_HOST,
  port: +process.env.DATABASE_PORT,
  username: process.env.DATABASE_USER,
  password: process.env.DATABASE_PASSWORD,
  database: process.env.DATABASE_DB,
  synchronize: false,
  dropSchema: false,
  logging: false,
  logger: 'file',
  entities: ['dist/**/*.entity{.ts,.js}'],
  migrations: ['src/migrations/**/*.ts'],
  subscribers: ['src/subscriber/**/*.ts'],
  migrationsTableName: 'migration_table',
});

```

Add the following code to your app.module.ts file with the following code
app.module.ts

```
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get('DATABASE_HOST'),
        port: configService.get('DATABASE_PORT'),
        username: configService.get('DATABASE_USER'),
        password: configService.get('DATABASE_PASSWORD'),
        database: configService.get('DATABASE_DB'),
        entities: ['dist/**/*.entity{.ts,.js}'],
        synchronize: false,
        autoLoadEntities: true,
        migrations: [__dirname + '/migrations/**/*{.ts,.js}'],
        seeds: [__dirname + '/seeds/**/*{.ts,.js}'],
        factories: [__dirname + '/factories/**/*{.ts,.js}'],
        cli: {
          migrationsDir: __dirname + '/migrations/',
        },
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AppController],
  providers: [],
})
export class AppModule {}

```

Update the package.json to include the following migrations commands
package.json

```
 "scripts": {
    ....
    "typeorm": "typeorm-ts-node-commonjs",
    "schema:sync": "npx typeorm-ts-node-commonjs schema:sync",
    "typeorm:cache": "npx typeorm-ts-node-commonjs cache:clear",
    "schema:drop": "npx typeorm-ts-node-commonjs -d ./src/database/data-source.ts",
    "migration:create": "typeorm migration:create ./src/migrations/schema-update",
    "migration:generate": "npx typeorm-ts-node-commonjs migration:generate ./src/migrations/schema-update -d ./src/database/data-source.ts",
    "migration:show": "npx typeorm-ts-node-commonjs migration:show -d ./src/database/data-source.ts",
    "migration:run": "npx typeorm-ts-node-commonjs migration:run -d  ./src/database/data-source.ts",
    "migration:revert": "npx typeorm-ts-node-commonjs migration:revert -d ./src/database/data-source.ts"
  }
```

Once you are done with the setup above you can run the following commands in your project root

1. ``npm run migration:create `` This will create an empty migration file where you can write your SQL in both UP and Down functions to either schema drop or create the schema.

2. ``npm run migration:generate `` This will generate SQL from your entities and you can find them inside migrations folder as per data-source.ts configuration.

3. ``npm run migration:run `` This will populate your database with the new database schema as per the migration file generated in 2, Now you have updated your database schema.

Note: Make sure you set synchronize: false in the production project otherwise if there a schema changes in your code, you might lose data in your existing database.

Feel free to check typeorm [typeorm.io](typeorm.io) and nestjs docs [https://docs.nestjs.com/](https://docs.nestjs.com/), for more information.

I want to give you one reason why we have dataSource.ts database configurations and why we have another database connection inside app.module.ts?. 
``Migration runs without NestJS runtime. NestJS will use app.module.ts database connection and migration will use dataSource.ts``