web-dev-qa-db-fra.com

NestJS + TypeORM: utilisez deux bases de données ou plus?

J'essaie depuis 2 jours de résoudre ce problème, peut-être que je manque simplement le point ici.

Mon objectif était d'écrire une application NestJS (avec TypeORM inclus) qui sert un RestAPI pour 2 ou 3 de mes petits projets, au lieu d'écrire une application NestJS pour chacun d'entre eux.

Jusqu'ici tout va bien, l'application est prête, fonctionne bien avec les projets individuels (qui résident dans des sous-dossiers avec leurs entités, contrôleurs, services, modules), mais je ne peux pas le faire fonctionner avec tous.

Le point semble être la configuration, j'utilise 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"
    } ]

Le message d'erreur dit:

[ExceptionHandler] Impossible de trouver la connexion par défaut car elle n'est définie dans aucun fichier de configuration orm

Bien sûr, "default" n'a pas pu être trouvé, car je fournis deux configurations avec des noms uniques différents de "default".

Dans ApplicationModule je pourrais fournir le nom de la connexion, comme ceci:

TypeOrmModule.forRoot( { name: "project1" } ),

mais alors cela ne fonctionnerait que pour un seul projet.

Je pourrais tout mélanger dans une config, mais alors j'aurais tout dans une base de données, le même utilisateur pour tous et peut-être mélanger les entités ...

Quelqu'un peut-il me donner un indice pour résoudre ce problème? Peut-être avec getConnection(<name>) dans chaque module, mais comment démarrer ensuite ApplicationModule?

Sincères amitiés,
sagerobert

9
sagerobert

Je viens d'essayer de configurer TypeORM avec plusieurs bases de données et un ormconfig.json et ça n'a pas marché du tout. Il semblait toujours utiliser la connexion default et quand aucune connexion par défaut (= sans nom explicite) n'a été trouvée, il a généré l'erreur correspondante.

Cela a bien fonctionné quand j'ai défini les connexions dans le app.module.ts à la place (j'ai supprimé 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' },
  })
]
5
Kim Kern

Pour plus de clarté et pour que d'autres développeurs viennent à ce poste:

De documentation NestJS :

Si vous ne définissez aucun nom pour une connexion, son nom est défini par défaut. Veuillez noter que vous ne devez pas avoir plusieurs connexions sans nom ou avec le même nom, sinon elles sont simplement remplacées.

L'une de vos connexions doit avoir l'un des éléments suivants:

  1. "name":"default"
  2. Sans aucun nom.

Je recommanderais de déclarer toutes vos connexions dans ormconfig.json et ne pas le déclarer dans le code.

Un exemple pour importer les connexions depuis 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: [...]
})

dans votre module (pas nécessairement le module racine, seuls les modules dont vous aurez besoin des connexions).

1
o.Nassie

Vous devez passer explicitement le nom de la connexion au même niveau à l'intérieur TypeOrmModule.forRoot ({name: 'db1Connection'}) au cas où vous utilisez plusieurs connexions à la base de données.

TypeOrmModule.forRootAsync({
  name: DB1_CONNECTION,
  imports: [ConfigModule],
  useClass: TypeormDb1ConfigService,
}),

TypeOrmModule.forRootAsync({
  name: DB2_CONNECTION,
  imports: [ConfigModule],
  useClass: TypeormDb2ConfigService,
})
0
Frozenex