内容
typeormでjoinせずに外部キーのIDを取得する方法について説明します。
version
typerom:0.3.19
DB:postgres:14.10
困り事
typeormのドキュメント
Many-to-one / one-to-many relations
を参考にリレーションを貼ると、selectしたときにテーブルをjoinしないと外部キーのIDが取得できませんでした。
entity
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm"
import { User } from "./User"
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number
@Column()
url: string
@ManyToOne(() => User, (user) => user.photos)
user: User
}
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm"
import { Photo } from "./Photo"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToMany(() => Photo, (photo) => photo.user)
photos: Photo[]
}
実行
import { AppDataSource } from "./data-source";
import { Photo } from "./entity/Photo";
import { User } from "./entity/User";
AppDataSource.initialize().then(async () => {
// Users
const user = new User();
user.name = `name`;
await AppDataSource.manager.insert(User, user);
const photo = new Photo();
photo.url = `url`;
await AppDataSource.manager.insert(Photo, photo);
const photoRepository = AppDataSource.getRepository(Photo);
const photos = await photoRepository.createQueryBuilder("photo").getMany();
console.log(photos);
});
コンソール出力(selectの結果)
外部キーがuserIdが取得できません。
[ Photo { id: 1, url: 'url' } ]
Join
UserとPhotoをJoinすれば取得できます。
import { AppDataSource } from "./data-source";
import { Photo } from "./entity/Photo";
import { User } from "./entity/User";
AppDataSource.initialize().then(async () => {
// Users
const user = new User();
user.name = `name`;
await AppDataSource.manager.insert(User, user);
// Photos
const photo = new Photo();
photo.url = `url`;
photo.user = user;
await AppDataSource.manager.insert(Photo, photo);
const photoRepository = AppDataSource.getRepository(Photo);
const photos = await photoRepository.createQueryBuilder("photo").innerJoinAndSelect("photo.user", "user").getMany();
console.log(photos);
});
コンソール出力(selectの結果)
外部キーがuserIdがUserのidとして取得できる。
[ Photo { id: 43, url: 'url', user: User { id: 43, name: 'name' } } ]
解決方法
View Entities
に記載のある方法でリレーションを貼るとjoinせずに外部キーが取得できました。
entity
Photoを以下のように修正
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from "typeorm";
import { User } from "./User";
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column()
url: string;
@Column()
userId: number
@ManyToOne(() => User)
@JoinColumn({ name: "userId" })
user: User;
}
コンソール出力(selectの結果)
外部キー(userId)が取得
[ Photo { id: 11, url: 'url', userId: 11 } ]