TypeORM を試している
環境は以下
- nodejs 23.4.0
- npm 10.9.2
- nestjs 10.0.0
- typeorm 0.3.20
TypeORM のデータソースでは エンティティクラスを直接指定するか、エンティティクラスのあるディレクトリを指定することができるはずだが、試してみてもディレクトリ指定ができない。
src/data-source.ts
import { DataSource } from 'typeorm';
import { Book } from './entities/Book';
export const AppDataSource = new DataSource({
type: 'postgres', // or your preferred database type
host: 'pg',
port: 5432,
username: 'testuser',
password: 'password',
database: 'testdb',
synchronize: true,
logging: true,
logger: 'advanced-console',
entities: [
'entities/*.ts',
], // Add your entities here
migrations: [
__dirname + '/data/migration/*.ts',
],
subscribers: [],
});
AppDataSource.initialize()
.then(() => {
console.log('Data Source has been initialized!');
})
.catch((err) => {
console.error('Error during Data Source initialization:', err);
});
src/entities/Book.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity("books")
export class Book {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
author: string;
@Column('text')
description: string;
@Column()
publishedYear: number;
@Column()
genre: string;
}
src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { BooksModule } from './admin/books/books.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppDataSource } from './data-source';
@Module({
controllers: [AppController],
providers: [AppService],
imports: [
TypeOrmModule.forRoot(AppDataSource.options),
BooksModule
],
})
export class AppModule {}
必要な設定は大体こんな感じ。 migration:create
も migration:generate
も migration:run
も正しく機能する。
ところが start:dev
して Book エンティティのリストを取得するような適当な controller を実行すると
[Nest] 22173 - 12/30/2024, 4:46:12 PM ERROR [ExceptionsHandler] No metadata for "Book" was found.
EntityMetadataNotFoundError: No metadata for "Book" was found.
at DataSource.getMetadata (/application/backend/node_modules/typeorm/data-source/src/data-source/DataSource.ts:450:30)
at Repository.get metadata (/application/backend/node_modules/typeorm/repository/src/repository/Repository.ts:53:40)
at Repository.find (/application/backend/node_modules/typeorm/repository/src/repository/Repository.ts:544:39)
at BooksController.findAll (/application/backend/src/admin/books/books.controller.ts:11:28)
at /application/backend/node_modules/@nestjs/core/router/router-execution-context.js:38:29
at InterceptorsConsumer.intercept (/application/backend/node_modules/@nestjs/core/interceptors/interceptors-consumer.js:12:20)
at /application/backend/node_modules/@nestjs/core/router/router-execution-context.js:46:60
at /application/backend/node_modules/@nestjs/core/router/router-proxy.js:9:23
at Layer.handle [as handle_request] (/application/backend/node_modules/express/lib/router/layer.js:95:5)
at next (/application/backend/node_modules/express/lib/router/route.js:149:13)
とエラーが出る。直前に(か、 start:dev
した直後)
query: SELECT version();
query: START TRANSACTION
query: START TRANSACTION
query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = 'public' AND "table_name" = 'typeorm_metadata'
query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = 'public' AND "table_name" = 'typeorm_metadata'
query: COMMIT
と出ているので typeorm_metadata
テーブルにメタデータを保管しておいてそれを使うつもりが失敗して要るっぽい。
各種情報見た感じ、 create table typeorm_metadata()
とかでテーブル作るような記述も見つかるが、結局何も起きない。
結論として、 entities
プロパティにエンティティクラスを全部指定するとまともに動作するのでそちらを選択することになる。
まあテーブル数が10個程度に収まるならそっちのほうが早いが、ちょっと規模が大きくなってくると多分つらい目にあう。