I'm trying since 2 days to solve this, perhaps I'm simply missing the point here.
My goal was to write a NestJS app (with TypeORM included) which serves a RestAPI for 2 or 3 of my little projects, instead of writing a NestJS-App for every single one of them.
So far so good, the app is ready, works well with the single projects (which resides in subfolders with their entities, controllers, services, modules), but I can't get it to run with all of them.
The point seems to be the configuration, I'm using ormconfig.json
:
[ {
"name": "Project1",
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "<username>",
"password": "<pwd>",
"database": "<database>",
"synchronize": false,
"entities": ["project1/*.entity.ts"],
"subscribers": ["project1/*.subscriber.ts"],
"migrations": ["project1/migrations/*.ts"],
"cli": { "migrationsDir": "project1/migrations" }
}, {
"name": "project2",
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "<another-username>",
"password": "<another-pwd>",
"database": "<another-database>",
"synchronize": false,
"entities": ["project2/*.entity.ts"],
"subscribers": ["project2/*.subscriber.ts"],
"migrations": ["project2/migrations/*.ts"],
"cli": { "migrationsDir": "project2/migrations"
} ]
The error message says:
[ExceptionHandler] Cannot find connection default because its not defined in any orm configuration files
Of course "default" couldn't be found, because I'm providing two configs with unique names different to "default".
In ApplicationModule I could provide the name of the connection, like this:
TypeOrmModule.forRoot( { name: "project1" } ),
but then it would work only for one project.
I could mix all in one config, but then I would have everything in one database, same user for all and perhaps mix up the entities...
Can someone give me a hint how to solve this?
Perhaps with getConnection(<name>)
in every module, but how to start the ApplicationModule then?
Kind regards,
sagerobert
I just tried setting up TypeORM with multiple databases and a ormconfig.json
and it did not work for me at all. It seemed to always use the default
connection and when no default (= without explicit name) connection was found it threw the corresponding error.
It did work though when I defined the connections in the app.module.ts
instead (I removed ormconfig.json
):
imports: [
...,
TypeOrmModule.forRoot({
name: 'Project1',
type: 'mysql',
host: 'localhost',
port: 3306,
username: '<username>',
password: '<pwd>',
database: '<database>',
synchronize: false,
entities: ['project1/*.entity.ts'],
subscribers: ['project1/*.subscriber.ts'],
migrations: ['project1/migrations/*.ts'],
cli: { migrationsDir: 'project1/migrations' },
}),
TypeOrmModule.forRoot({
name: 'project2',
type: 'mysql',
host: 'localhost',
port: 3306,
username: '<another-username>',
password: '<another-pwd>',
database: '<another-database>',
synchronize: false,
entities: ['project2/*.entity.ts'],
subscribers: ['project2/*.subscriber.ts'],
migrations: ['project2/migrations/*.ts'],
cli: { migrationsDir: 'project2/migrations' },
})
]
For clarity and for other developers to come to this post:
From NestJS documentation:
If you don't set any name for a connection, its name is set to default. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they simply get overridden.
One of your connections must have one of the following:
"name":"default"
I would recommend to declare all your connections in ormconfig.json
and not declare it in code.
An example to import the connections from ormconfig.json
:
@Module({
imports: [TypeOrmModule.forFeature([Entity1, Entity2]), //This will use default connection
TypeOrmModule.forRoot({name: 'con1'}), // This will register globaly con1
TypeOrmModule.forRoot({name: 'con2'}), // This will register globaly con2
controllers: [...],
providers: [...],
exports: [...]
})
in your module (not have to be the root module, only the modules you will need the connections).
You need to explicitly pass the connection name at the same level inside TypeOrmModule.forRoot({ name: 'db1Connection' }) incase you are using multiple database connections.
TypeOrmModule.forRootAsync({
name: DB1_CONNECTION,
imports: [ConfigModule],
useClass: TypeormDb1ConfigService,
}),
TypeOrmModule.forRootAsync({
name: DB2_CONNECTION,
imports: [ConfigModule],
useClass: TypeormDb2ConfigService,
})
for those who face this problem , this is my solution
AppModule
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [
database,
databaseAllo #<= my second database
]
}),
TypeOrmModule.forRootAsync({
useFactory: (configs: ConfigService) => configs.get("db_config"),
inject: [ConfigService],
}),
TypeOrmModule.forRootAsync({
name:"db_allo", #<= create connection to my second db
useFactory: (configs: ConfigService) => configs.get("db_config_allo"),
inject: [ConfigService],
}),
AuthModule,
JwtAuthModule
],
controllers: []
})
export class AppModule {}
my project module ( contain table from second db )
@Module({
imports: [
TypeOrmModule.forFeature([AlloMpcTable], "db_allo" #<= call connection again),
],
providers: [
AlloRepository
],
exports: [AlloRepository],
controllers: [],
})
export class AlloModule {}
my project repository
@Injectable()
export class AlloRepository extends BaseRepository<AlloMpcTable> {
constructor(
@InjectRepository(AlloMpcTable, "db_allo") #<= you need to call connection again
private readonly allo: Repository<AlloMpcTable>,
) {
super(allo)
}
public async Find(id: number): Promise<AlloMpcTable> {
return await this.allo.findOne(id)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With