TypeOrm:RepositoryNotFoundError 播种时在 NestJS 中
TypeOrm:RepositoryNotFoundError in NestJS while seeding
我正在尝试使用 NestJS 和 TypeORM 为我的数据库做种。
我有一个创建 exercise
table 的迁移文件和一个将 ExerciseEntity
插入 table 的种子文件。这些文件之间的主要区别是迁移文件直接运行查询:
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\dev84903747780-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
使用以下 webpack 配置编译和提供应用程序:
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
来注入配置服务。我怀疑当播种机执行时,存储库可能尚未注册。这将解释稍后,当 运行 Web 应用程序时,该服务可以访问存储库。
知道如何解决这个问题吗?
我的配置是错误的还是遗漏了什么?播种机是否有办法等待存储库被注册,如果这是问题所在?
编辑:
它与 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;
}
和错误一样。
问题来自当前的 TypeORM 版本 (0.2.24)。
我切换到 0.2.22 并且它工作了,没有改变任何其他东西。
这是我用这篇文章打开的问题,最后询问他们希望什么时候修复它:
https://github.com/typeorm/typeorm/issues/5781
这里有一些问题似乎在上一个版本中讨论了这个问题:
https://github.com/typeorm/typeorm/issues/5676
我正在尝试使用 NestJS 和 TypeORM 为我的数据库做种。
我有一个创建 exercise
table 的迁移文件和一个将 ExerciseEntity
插入 table 的种子文件。这些文件之间的主要区别是迁移文件直接运行查询:
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\dev84903747780-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
使用以下 webpack 配置编译和提供应用程序:
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
来注入配置服务。我怀疑当播种机执行时,存储库可能尚未注册。这将解释稍后,当 运行 Web 应用程序时,该服务可以访问存储库。
知道如何解决这个问题吗?
我的配置是错误的还是遗漏了什么?播种机是否有办法等待存储库被注册,如果这是问题所在?
编辑:
它与 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;
}
和错误一样。
问题来自当前的 TypeORM 版本 (0.2.24)。
我切换到 0.2.22 并且它工作了,没有改变任何其他东西。
这是我用这篇文章打开的问题,最后询问他们希望什么时候修复它:
https://github.com/typeorm/typeorm/issues/5781
这里有一些问题似乎在上一个版本中讨论了这个问题:
https://github.com/typeorm/typeorm/issues/5676