typeorm icon indicating copy to clipboard operation
typeorm copied to clipboard

TypeOrmModule.forRoot() should accept connection name

Open IntellectProductions opened this issue 6 years ago • 13 comments

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

TypeOrmModule.forRoot('default') is throwing as invalid code even though in the documentation states that it accepts the same arguments as createConnection() does in Typeorm.

[{
  "name": "default",
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "",
  "password": "",
  "database": "",
  "entities": ["src/**/**.entity{.ts,.js}"],
  "synchronize": false,
  "migrationsTableName": "migrations",
  "migrations": ["src/database/migrations/*{.ts,.js}"],
  "cli": {
    "migrationsDir": "src/database/migrations"
  }
}, {
  "name": "seed",
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "",
  "password": "",
  "database": "",
  "entities": ["src/**/**.entity{.ts,.js}"],
  "synchronize": false,
  "migrationsTableName": "seeds",
  "migrations": ["src/database/seeds/*{.ts,.js}"],
  "cli": {
    "migrationsDir": "src/database/seeds"
  }
}]

Expected behavior

It should pick the connection name from your ormconfig.js or json file like Typeorm does.

What is the motivation / use case for changing the behavior?

To stay up to date with Typeorm's codebase.

Environment


Nest version: 5.7.3

 
For Tooling issues:
- Node version: 10.5.0  
- Platform:  Mac 

IntellectProductions avatar Feb 28 '19 22:02 IntellectProductions

@IntellectProductions Is this only to stay up to date with Typeorm's codebase or/and to configure @nestjs/typeorm to create a specific connection by name?

I am facing the same issue now. My ormconfig.json has multiple connections and I cannot find a way to instruct it to use this connection or that.

cc: @kamilmysliwiec

bhaidar avatar Mar 04 '19 22:03 bhaidar

@bhaidar I hate the way I'm doing it now, but I'm basically duplicating my config inside my forRoot() method for the connection I want to use. I'm not very familiar with Typeorm's base code to actually try to do a PR or anything of that nature as much as I want to!

IntellectProductions avatar Mar 05 '19 14:03 IntellectProductions

Same issue here, I cannot get 2 connections running by using the ormconfig.json config.

Is there any way to enhance this module so that it can support this?

pxr64 avatar Aug 01 '19 07:08 pxr64

Edit: I just realized this issue is specifically for loading from the ormconfig.json file but I will leave this comment in case anyone finds it useful and chooses to use a different way of configuring the connections.

This works for us but the documentation is definitely unclear on this point. Note that the connection name is passed outside of the connection configuration object.

const connectionName = 'other';

TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      name: connectionName,
      useFactory: async (configService: ConfigService) => {
        return {
          ...configService.get<ConnectionOptions>(connectionName),
          entities: [__dirname + '/**/*.entity.{js,ts}'],
        };
      },
    }),

dsbert avatar Mar 11 '20 16:03 dsbert

@dsbert I'm still not sure, are you suggesting I pass in a dummy name and convince nestjs/typeorm to load the correct configuration from ormconfig.json?

acepace avatar Apr 09 '20 19:04 acepace

@acepace No, the important thing is that when calling forRootAsync, the connection name has to be passed as a separate parameter outside of the connection options. So if you are just passing in the ormconfig.json, that won't work. You also need to set the connection name explicitly. You don't need to do this if you are calling forRoot. Here is an example.

TypeOrmModule.forRoot(
	{
      name: 'conn1', // This field sets the connection when calling forRoot
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }
),
TypeOrmModule.forRootAsync(
      name: 'conn2', // This field sets the connection when calling forRootAsync
      useFactory: () => {
      return {
        name: 'conn2', // This field is ignored when calling forRootAsync
        type: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'root',
        database: 'test',
        entities: [],
        synchronize: true,
      };
    },
),

dsbert avatar Apr 10 '20 04:04 dsbert

@dsbert , thanks for the tip here!

I recently came across a similar issue, I'm simply relying on the forRoot and when I use the cms ( or engine) database and entity alone everything seems to work fine but when combined together, the connection which comes after, doesn't respond at all.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CmsTeamModule } from './modules/wcms/CmsTeam/CmsTeam.module';
import { EngTrophyModule } from './modules/engine/EngTrophy/EngTrophy.module';


@Module({
  imports: [
    TypeOrmModule.forRoot({
      'name': 'wcms',
      'type': 'mysql',
      'host': 'localhost',
      'port': 3306,
      'username': 'ci',
      'password': 'ci',
      'database': 'ci_wcms',
      'entities': [
        'dist/**/*.entity.js',
      ],
      'synchronize': false,
        'logging': true,
      },
    ),

    CmsTeamModule,


    TypeOrmModule.forRoot({
        'type': 'mysql',
        'host': 'localhost',
        'port': 3306,
        'username': 'ci',
        'password': 'ci',
        'database': 'ci_engine',
        'entities': [
          'dist/**/*.entity.js',
        ],
        'synchronize': false,
        'logging': true,
      },
    ),

    EngTrophyModule,

  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Am I making an obvious mistake here?

abhi18av avatar May 20 '20 15:05 abhi18av

Any update here? I'm seeing some oddities around this too.

kevinelliott avatar May 23 '20 01:05 kevinelliott

[ ] Regression [x] Bug report [ ] Feature request [ ] Documentation issue or request [ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

taeger100 avatar Jun 04 '20 13:06 taeger100

// Database Default
TypeOrmModule.forRootAsync({
  useFactory: async (config: ConfigService) => ({
    entities: [`${__dirname}/entity/!(foo)/*.{js,ts}`],
    subscribers: [`${__dirname}/subscriber/!(foo)/*.{js,ts}`],
    migrations: [`${__dirname}/migration/!(foo)/*.{js,ts}`],
    ...config.get('db')[0],
  }),
  inject: [ConfigService],
}),
// Database Foo
TypeOrmModule.forRootAsync({
  name: 'foo',
  useFactory: async (config: ConfigService) => ({
    entities: [`${__dirname}/entity/foo/*.{js,ts}`],
    subscribers: [`${__dirname}/subscriber/foo/*.{js,ts}`],
    migrations: [`${__dirname}/migration/foo/*.{js,ts}`],
    ...config.get('db')[1],
  }),
  inject: [ConfigService],
}),

The above code has no problem running(nest start --watch), but testing gives an error.

let app: INestApplication;
let httpServer: unknown;

beforeAll(async () => {
  const moduleFixture = await Test.createTestingModule({
    imports: [AppModule],
  }).compile();

  app = moduleFixture.createNestApplication();
  await app.init();

  httpServer = app.getHttpServer();
});

image

// Database Foo
TypeOrmModule.forRootAsync({
  name: 'foo',
  useFactory: async (config: ConfigService) => ({
    name: 'foo',
    entities: [`${__dirname}/entity/foo/*.{js,ts}`],
    subscribers: [`${__dirname}/subscriber/foo/*.{js,ts}`],
    migrations: [`${__dirname}/migration/foo/*.{js,ts}`],
    ...config.get('db')[1],
  }),
  inject: [ConfigService],
}),

Add name inside the useFactory as above also solved the problem.

https://github.com/nestjs/typeorm/blob/6acde561118436a2db972f0630dd2eaf3794bcd1/lib/typeorm-core.module.ts#L107 This error occurs because the name cannot be found in this.options in the code above. It seems that the name value entered in forRootAsync needs to be added to this.options

CatsMiaow avatar Jul 29 '20 10:07 CatsMiaow

+1 for connection name support

joaogolias avatar Oct 27 '20 15:10 joaogolias

I don't get it, I'm already using named connections for a long time in my side project. How is it an issue?

omidh28 avatar Apr 11 '21 21:04 omidh28

Seems like it won't happen, see the comment: https://github.com/nestjs/typeorm/pull/1030#issuecomment-1001496472

fadeevab avatar Jan 21 '22 20:01 fadeevab