Search code examples
typeormnest

Running migrations with `useFactory`


I have the app in nestjs with the app.module.ts containing the following configuration:

import { ConfigModule, ConfigService } from '@nestjs/config';
import {
  TypeOrmModuleAsyncOptions,
  TypeOrmModuleOptions,
} from '@nestjs/typeorm';
import { DataSource } from 'typeorm';  

export const typeOrmAsyncConfig: TypeOrmModuleAsyncOptions = {
  imports: [ConfigModule],
  inject: [ConfigService],
  name: 'nameA',
  useFactory: (configService: ConfigService) => ({
    type: 'postgres',
    host: configService.get('DB_HOST'),
    port: parseInt(configService.get('DB_PORT') || '5432'),
    username: configService.get('DB_USER'),
    password: configService.get('DB_PASSWORD'),
    database: configService.get('DB_NAME'),
    entities: [__dirname + './../**/*.entity{.ts,.js}'],
    migrations: [__dirname + '/../database/migrations/*{.ts,.js}'],
    synchronize: false,
    cli: {
      entitiesDir: __dirname + './../**/*.entity{.ts,.js}',
    },
    ssl: configService.get('DB_SSL') === 'true',
  }),
};

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRootAsync(typeOrmAsyncConfig),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

I have typeorm installed globally and have migration files generated in the specified paths above, but, I get a dataSource not found error.

typeorm migration:run output:

Runs all pending migrations.

Options:
  -h, --help         Show help                                         [boolean]
  -d, --dataSource   Path to the file where your DataSource instance is defined.
                                                                      [required]
  -t, --transaction  Indicates if transaction should be used or not for
                     migration run. Enabled by default.     [default: "default"]
  -v, --version      Show version number                               [boolean]

Missing required argument: dataSource

How do I export a datasource when I'm using the useFactory inside of the app.module.ts and solve this issue?


Solution

  • Since typeorm 0.3.x cli needs a datasource and ormconfig.json is no more supported. Also cli commands have changed too. You can define separate configurations for nestjs and typeorm-cli.

    src/config/database-config.ts

        import 'dotenv/config';
        import { DataSourceOptions } from 'typeorm';
        
        const databaseConfig: DataSourceOptions = {
          name: 'default',
          type: 'better-sqlite3',
          database: process.env.DB_NAME,
          entities: [__dirname + '/../entities/*.entity.ts'],
          migrations: [__dirname + '/../migrations/*{.ts,.js}'],
          synchronize: false,
          logging: true,
          migrationsRun: true
        };
        
        export default databaseConfig;
    

    then for typeorm cli

    src/config/data-source.ts

        import { DataSource } from 'typeorm';
        import databaseConfig from './database-config';
        
        export const AppDataSource = new DataSource(databaseConfig);
    

    and for nestjs app-module

    src/config/typeorm-config.ts like so: TypeOrmModule.forRootAsync(typeOrmAsyncConfig)

        import { ConfigModule, ConfigService } from '@nestjs/config';
        import {
          TypeOrmModuleAsyncOptions,
          TypeOrmModuleOptions,
        } from '@nestjs/typeorm';
        import databaseConfig from './database-config';
        
        export const typeOrmConfig: TypeOrmModuleOptions = databaseConfig;
        
        export const typeOrmAsyncConfig: TypeOrmModuleAsyncOptions = {
          imports: [ConfigModule],
          inject: [ConfigService],
          useFactory: async (): Promise<TypeOrmModuleOptions> => {
            return databaseConfig;
          },
        };
    

    package.json scripts (change yarn run if needed)

        {
        "typeorm:cli": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli -d src/config/data-source.ts",
        "migration:generate": "yarn run typeorm:cli migration:generate",
        "migration:create": "yarn run typeorm:cli migration:create",
        "migration:run": "yarn run typeorm:cli migration:run",
        "migration:revert": "yarn run typeorm:cli migration:revert"
        }
    

    for example if you need to generate a new migration complete path needed in terminal

    yarn run migration:generate src/migrations/newMigrationName