typeorm, TypeError: this.subQuery is not a function appears 에러 해결 [TIL / TypeScript]

알락·2022년 12월 25일
0
post-custom-banner

typescript banner

배경

프로젝트의 백엔드에서 타입스크립트를 사용하기로 했다. 기존 JS로 구현하는 express 서버의 많은 부분인 변경이 되었다. 그리고 특히 이전까지는 mysql에 쿼리문과 CRUD 명령을 할 때, Sequelize라는 ORM을 사용해왔었는데, 타입스크립트에서는 타입스크립트 지원 문제로 typeorm을 사용하게 되었다. 덕분에 이전엔 경험하지 못 했던 에러들을 목격하게 된다.

this.subQuery is not a function appears

subQuery meme

사실 이 에러는 정말 기본적인 typeorm 설정을 모르고 맹목적으로 코딩을 하면 내는 문제이다.
이 에러를 낸 경위를 먼저 살펴보겠다. mysql에 express 서버를 처음 연결하는 단계였다.

[data-source 코드]

import { DataSource } from "typeorm";
import User from "../entity/User";
require("dotenv").config();

export const AppDataSource = new DataSource({
    type: "mysql",
    host: "localhost",
    port: 3306,
    database: "OPENPOOL",
    username: process.env.DATABASE_USERNAME,
    password: process.env.DATABASE_PASSWORD,
    synchronize: true,
    logging: true,
    entities: [User],
})

default AppDataSource

[User Entity]

import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export default class User {
    @PrimaryGeneratedColumn()
    id: number
    
    @Column()
    address: string
}

[Controller]

import AppDataSource from "../db/data-source";
import {Request, Response} from "express";
import User from "../entity/User";

export const addUser = async (req : Request, res: Response)=>{
    const address : string = req.body.address;

    await AppDataSource
    .createQueryBuilder()
    .insert()
    .into(User)
    .values([{
        address: address
    }]).execute();

    return res.status(200).send("success db");
}

데이터베이스의 User 테이블에 address값만 갖는 레코드를 추가하는 아주 간단한 코드다. 하지만 이코드를 통해서 addUser를 실행시키면 아래와 같은 에러가 발생한다.

TypeError: this.subQuery is not a function appears

해결

대부분의 해결방법

위와 같은 에러에 대한 질문에 많은 답변이 data-source에서 데이터베이스 연결 설정을 해주는 부분의 entities의 값을 제대로 설정하라고 조언한다.

이를테면 아래와 같이 말이다.

[조언 방식]

{
  	// 생략...
  
	entities : ["src/entity/*.{ts,js}"]
  
  	// 생략...
}

하지만 필자의 경우에는 생성된 모델 데이터인 User.ts를 모듈로 불러와 바로 입력했기 때문에 사실 형태만 다르지 충분히 작동 가능한 설정방식 이었다.

[필자 방식]

import User from "../entity/User";

{
  	// 생략...
  
	entities : [User]
  
  	// 생략...
}

보통의 경우에는 이 설정을 제대로 안해줘서 생기는 문제라 발생하는 문제들인 듯하다. 하지만 필자의 경우는 달랐다.

데이터베이스 synchronize 문제

필자의 경우는 User Entity 파일에 모델링 되어 있는 Scheme이 실제 Local DBMS에 반영이 안되어 있어서 문제였다. 더 쉽게 말하자면 User Table이 필자 Database에 없었던 것이다.
이 문제는 직접 mysql에서 테이블을 생성해줘도 되고, data-source에서 데이터베이스 연결 설정을 할 때 ORM으로 데이터베이스를 초기화해도 해결을 할 수 있다.

필자는 후자의 방법을 선택하여 해결하였다.

import { DataSource } from "typeorm";
import User from "../entity/User";
require("dotenv").config();

const AppDataSource = new DataSource({
    type: "mysql",
    host: "localhost",
    port: 3306,
    database: "OPENPOOL",
    username: process.env.DATABASE_USERNAME,
    password: process.env.DATABASE_PASSWORD,
    synchronize: true,
    logging: true,
    entities: [User],
})

if (!AppDataSource.isInitialized){
    AppDataSource.initialize()
    .then(()=>{
        console.log("db init success");
    })
    .catch((error)=> console.log(error));
}

export default AppDataSource

정리

  • this.subQuery 문제는 entity 등록만이 아닌 데이터베이스 초기화에서도 발생할 수 있는 에러이다.
profile
블록체인 개발 공부 중입니다, 프로그래밍 공부합시다!
post-custom-banner

0개의 댓글