If you are building a NestJS application and want to use a PostgreSQL database with TypeORM migration, then this article will guide you on creating and running migrations efficiently.
First, create a NestJS application with Nest CLI:
nest new my-app
Next, install the required packages for TypeORM, Postgres, and Configuration:
npm install --save @nestjs/typeorm typeorm pg @nestjs/config
Create a file to store the TypeORM configuration in the src/config/typeorm.ts
directory. This file should export a TypeORM configuration object and a connection source object.
import { registerAs } from "@nestjs/config";
import { config as dotenvConfig } from 'dotenv';
import { DataSource, DataSourceOptions } from "typeorm";
dotenvConfig({ path: '.env' });
const config = {
type: 'postgres',
host: `${process.env.DATABASE_HOST}`,
port: `${process.env.DATABASE_PORT}`,
username: `${process.env.DATABASE_USERNAME}`,
password: `${process.env.DATABASE_PASSWORD}`,
database: `${process.env.DATABASE_NAME}`,
entities: ["dist/**/*.entity{.ts,.js}"],
migrations: ["dist/migrations/*{.ts,.js}"],
autoLoadEntities: true,
synchronize: false,
}
export default registerAs('typeorm', () => config)
export const connectionSource = new DataSource(config as DataSourceOptions);
Load TypeORM into app.module.ts
to use it in your NestJS application:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import typeorm from './config/typeorm';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [typeorm]
}),
TypeOrmModule.forRootAsync({
inject: [ConfigService],
useFactory: async (configService: ConfigService) => (configService.get('typeorm'))
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
Create a .env file in the src/
directory to define the variables in your typeorm.ts
file:
DATABASE_HOST=postgres
DATABASE_PORT=5432
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=dev-secret
DATABASE_NAME=postgres
Add the TypeORM migration commands into your package.json
file:
"scripts": {
// ...
"typeorm": "ts-node ./node_modules/typeorm/cli",
"migration:run": "npm run typeorm migration:run -- -d ./src/config/typeorm.ts",
"migration:generate": "npm run typeorm -- -d ./src/config/typeorm.ts migration:generate ./src/migrations/$npm_config_name",
"migration:create": "npm run typeorm -- migration:create ./src/migrations/$npm_config_name",
"migration:revert": "npm run typeorm -- -d ./src/config/typeorm.ts migration:revert"
},
To execute migration, use the following command:
npm run migration:run
To create a new migration, use the following command:
npm run migration:create --name=your_migration_name
That's it! With this guide, you should now be able to use TypeORM migration with Postgres in your NestJS application efficiently.
Top comments (15)
Good explanation!!!
Wow! This article is a huge time saver for me.
Thank you so much for sharing your knowledge Amir
Thanks man! Saved my day.
Thanks~!
Thanks for this it worked 🙏🏽
thanks for this, was really helpful
Thank you, helped a lot!
Thanks for the content, it helped me a lot!
thanks for the great article
just note that the windows users must use
"migration:generate": "npm run typeorm -- -d ./src/config/typeorm.ts migration:generate ./src/migrations/%npm_config_name%",
"migration:create": "npm run typeorm -- migration:create ./src/migrations/%npm_config_name%",
for the scripts
Hi Sir, when do follow your instructment, the migration file is generated at root folder,
I added those lines to customize migration folder, but not working,
how i do that
cli: {
migrationsDir: './src/database/migrations',
},
Article should be reworked. Stuff is presented without explanation, the most important is to UNDERSTAND what you are doing, and no beeing a 'copy pasta' developer.
What does your config service contains ?
Why do you load your entities manually and then add 'autoLoad: true' ? You give the impression you don't understand what you are doing.
you must be a delight to work with
I agree with you Mr.Green.
This method only works when you're working with JavaScript, but if you're working with TypeScript, it doesn't work.
Also, remember that when using nestjs, Nestjs automatically handles Path aliases resolving. You can't simply assume this script will work even if you just run it with typeorm-ts-node-esm or typeorm-ts-node-commonjs because that's not enough to resolve the path aliases.
And, nonetheless, you didn't mention anything related to the edge cases when using ESM or commonjs.
Thanks for this. Well done!