TypeOrm: RepositoryNotFoundError в Nest JS при заполнении - PullRequest
0 голосов
/ 29 марта 2020

Я пытаюсь заполнить базу данных, используя Nest JS и TypeORM.

У меня есть файл миграции, который создает таблицу exercise, и файл заполнения, который вставляет ExerciseEntity в таблицу , Основное различие между этими файлами заключается в том, что файл миграции выполняет запросы напрямую:

public async up(queryRunner: QueryRunner): Promise<any> {
  await queryRunner.query(
    `CREATE TABLE ...`
  );
}

, а файл заполнения получает репозиторий:

public async up(queryRunner: QueryRunner): Promise<any> {
  await queryRunner.manager.getRepository<ExerciseEntity>(ExerciseEntity).save(
    someExerciseEntity
  );
}

Этот getRepository является тем, который создает ошибка.

RepositoryNotFoundError: No repository for "ExerciseEntity" was found. Looks like this entity is not registered in current "default" connection?
    at new RepositoryNotFoundError (C:\Users\Dev\Documents\team-management\src\error\RepositoryNotFoundError.ts:10:9)
    at EntityManager.getRepository (C:\Users\Dev\Documents\team-management\src\entity-manager\EntityManager.ts:1194:19)
    at SeedExercises1584903747780.<anonymous> (C:\Users\Dev\Documents\team-management\dist\apps\api\_seeds\dev\webpack:\_seeds\dev\1584903747780-SeedExercises.ts:7:31)

В сервисе я получаю хранилище и сохраняю сущности без проблем. Проблема возникает только во время заполнения.

Я регистрирую TypeORM следующим образом:

// app.module.ts
@Module({})
export class AppModule implements NestModule {
  static forRoot(): DynamicModule {
    return {
      module: AppModule,
      imports: [
        ConfigModule.forRoot({
          envFilePath: '.env.dev',
          validationSchema: validationSchema()
        }),
        TypeOrmModule.forRootAsync({
          imports: [ConfigModule],
          inject: [ConfigService],
          useFactory: async (configService: ConfigService) => databaseProviders(configService)
        }),
        ExercisesModule.forRoot()
      ]
    };
  }
}

где:

// database.provider.ts
export const databaseProviders = (configService: ConfigService) => {
  const normalizePath = (_path: string) => (path.normalize(path.join(__dirname, _path)));

  const commonDB: TypeOrmModuleOptions = {
    type: 'sqlite',
    entities: [...exercisesEntities]
  };
  // exerciseEntities comes from an index.ts in an exercise library
  // import { ExerciseEntity } from './exercise.entity';
  // export const exercisesEntities = [ExerciseEntity];

  const defaultDB: TypeOrmModuleOptions = {
    ...commonDB,
    database: path.join(
      configService.get('APP_ROOT_PATH', '.'),
      configService.get('TYPEORM_DATABASE', 'gym-dev.sqlite')
    ),
    logging: configService.get<boolean>('TYPEORM_ENABLE_LOGGING', true) ? ['query', 'error'] : [],
    cache: true,
    synchronize: configService.get<boolean>('TYPEORM_SYNCHRONIZE', false),
    migrations: [normalizePath('_migrations/*.js'), normalizePath('_seeds/dev/*.js')],
    migrationsRun: configService.get<boolean>('TYPEORM_MIGRATIONS_RUN', true),
    dropSchema: configService.get<boolean>('DROP_SCHEMA', false)
  };

  return defaultDB;
};

Я использую nrwl/nx для компиляции и обслуживания приложение, использующее следующую конфигурацию веб-пакета:

module.exports = function(config, context) {
  const baseDirectory = path.resolve(config.output.path);

  const entityPaths = ['libs/feature/api/**/entities/*.js'];
  const migrationPaths = ['_migrations/*.js', '_seeds/**/*.js'];
  config.entry = {
    ...config.entry,
    ...getEntityEntries(entityPaths),
    ...getMigrationEntries(migrationPaths)
  };
  // getEntries functions allows the compilation of entities and migrations

  // Output
  config.output = {
    path: baseDirectory,
    filename: '[name].js',
    libraryTarget: 'commonjs'
  };

  return config;
};

Моя dist структура в конечном итоге выглядит так:

dist
|-apps
  |-api
    |-_migrations  // contains compiled migrations
    |-_seeds       // contains compiled seeders
    |-lib
      |-entities   // contains compiled entities
    |-main.js

Как видно из app.module.ts, я использую TypeOrmModule.forRootAsync, чтобы иметь возможность внедрить службу конфигурации. Я подозреваю, что, возможно, когда будут запущены сеялки, хранилища еще не зарегистрированы. Это объясняет, что позже, во время работы веб-приложения, сервис может получить доступ к хранилищу.

Есть идеи, как мне это решить?
Моя конфигурация неверна или что-то не так? Есть ли в сеялке способ дождаться регистрации репозиториев, если в этом проблема?

РЕДАКТИРОВАТЬ:
Это не имеет ничего общего с TypeOrmModule.forRootAsync. Я сделал следующие изменения:

// app.module.ts
@Module({})
export class AppModule implements NestModule {
  static forRoot(): DynamicModule {
    return {
      module: AppModule,
      imports: [
        ConfigModule.forRoot({
          envFilePath: '.env.dev',
          validationSchema: validationSchema()
        }),
        TypeOrmModule.forRoot(databaseProvidersSync()),
        ExercisesModule.forRoot()
      ]
    };
  }
}
// database.providers.ts
export const databaseProvidersSync = () => {
  const normalizePath = (_path: string) => (path.normalize(path.join(__dirname, _path)));
  const defaultDB: TypeOrmModuleOptions = {
    type: 'sqlite',
    entities: [...exercisesEntities],
    database: path.normalize(`C:\\Users\\Dev\\Documents\\team-management\\gym-dev.sqlite`),
    logging: ['query', 'error'],
    cache: true,
    synchronize: false,
    migrations: [normalizePath('_migrations/*.js'), normalizePath('_seeds/dev/*.js')],
    migrationsRun: true,
    dropSchema: true
  }

  return defaultDB;
}

И ошибка та же.

1 Ответ

0 голосов
/ 29 марта 2020

Проблема связана с текущей версией TypeORM (0.2.24).

Я переключился на 0.2.22, и он работал, не меняя ничего.

Вот проблема, которую я открыл с этим текстом, и в конце спрашиваю, когда они ожидают, что он будет исправлен : https://github.com/typeorm/typeorm/issues/5781
И здесь есть проблема, которая говорит об этой проблеме в последней версии:
https://github.com/typeorm/typeorm/issues/5676

...