#rxjs #graphql #nestjs #typeorm
Вопрос:
У меня есть перехватчик, который в основном закрывает соединение с базой данных, когда запрос выполнен:
export class TransactionInterceptor implements NestInterceptor {
public async intercept(context: ExecutionContext, next: CallHandler) {
//some code
return next.handle().pipe(
finalize(async () => {
await session.queryRunner.release();
})
);
}
Проблема в том, что когда я использую graphql и мне нужно загрузить отношения, отношения загружаются после session.queryRunner.release()
, поэтому я получил ошибку "Query runner already released. Cannot run queries anymore"
от typeorm
Если я удалю queryRunner.release() из перехватчика, graphql будет работать нормально, но соединения в базе данных больше не будут закрыты.
Вот один из моих используемых решателей:
@Query(() => ChecklistModel, { name: 'checklistModel' })
public async getOne(@Args('id', { type: () => Int }) id: number) {
return this.repositoryService.get(ChecklistModel).findOne({ where: { id } });
}
@ResolveProperty('checklist_groups', type => [ChecklistGroup])
public async checklist_groups(@Parent() parent: ChecklistModel, @Context() { checklistGroupLoader }: IGraphQLContext): Promise<ChecklistGroup[]> {
return checklistGroupLoader.load(parent.id);
}
И загрузчик контрольных списков:
const checklistGroupLoader = () => new DataLoader(async ids => {
const checklistGroups = await session.manager.getRepository('checklist_group')
.createQueryBuilder('checklist_group')
.where('checklist_model_id IN(:...ids)', { ids: ids })
.getMany();
const genreIdToBooks: { [key: string]: ChecklistGroup[] } = {};
checklistGroups.forEach((checklistGroup) => {
const { checklist_model_id } = (checklistGroup as ChecklistGroup);
if (!genreIdToBooks[checklist_model_id]) {
genreIdToBooks[checklist_model_id] = [(checklistGroup as ChecklistGroup)];
} else {
genreIdToBooks[checklist_model_id].push((checklistGroup as ChecklistGroup));
}
});
return (ids as number[]).map((id) => genreIdToBooks[id]);
});