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
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.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.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 and nestjs docs 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
Top comments (5)
Thank you , you just saved my job
What if i had multiple databases? Here we created an script because we couldn't make it work with datasources.
This is the most up-to-date implemetation! Spend hours looking for this! Thanks!
Thank you
Thank you for your help, I didn’t find anything working in the official documentation and Github (maybe I didn’t look well :)) you helped a lot!