Express Sequelize 정의 방법

2021. 8. 11. 11:17Programming/Nodejs

728x90

class로 정의 후 init

// User.ts
import * as sequelize from "sequelize";
import userdb from "../../database/userdb";

class User extends sequelize.Model{
    id: number;
      name: string;
}
User.init({
  id:{
    autoIncrement: true,
    type: DataTypes.INTEGER.UNSIGNED,
    allowNull: false,
    primaryKey: true
  },
  name:{
    type: DataTypes.STRING(30),
    allowNull: true
  }},{
  sequelize: userdb,
  tableName: 'user_info',
  timestamps: false
});

export {
    User
};

init() method로 Sequelize를 정의하는 것은 변경되지 않는 DB를 정의하기에 깔끔하고, init을 하고 아래에서 association도 정의해줄 수 있으므로 편리하다.

다른 방법으로는

define

이 있다. sequelize.define(); 을 하면 ModelCtor 객체가 리턴된다.

import {Sequelize, Model, DataTypes} from "sequelize";

const userModel = (sequelize: Sequelize) => {
    const User = sequelize.define<User>("users",
        {
            id: {
                field: "id",
                autoIncrement: true,
                type: DataTypes.INTEGER.UNSIGNED,
                allowNull: false,
                primaryKey: true
            },
            name: {
                field: "name",
                type: DataTypes.STRING(20),
                allowNull: false,
                defaultValue: ""
            }
        },
        {
            schema: "test",
            tableName: "users",
            hasTrigger: true,
            timestamps: false
        });

    return User;
};

export {
    userModel,
};

이런식으로 하면 userModel을 부를 때 sequelize 객체를 인자로 전달하면 User 모델을 얻을 수 있다.

위에서 조금 변형시키면

import {Sequelize, Model, DataTypes} from "sequelize";

const officeUserModel = (sequelize: Sequelize, partition:string) => {
    const modelName = "user" + partition;

    const User = sequelize.define<User>(modelName,
        {
            id: {
                field: "id",
                autoIncrement: true,
                type: DataTypes.INTEGER.UNSIGNED,
                allowNull: false,
                primaryKey: true
            },
            name: {
                field: "name",
                type: DataTypes.STRING(20),
                allowNull: false,
                defaultValue: ""
            }
        },
        {
            schema: "test"+partition,
            tableName: "users",
            hasTrigger: true,
            timestamps: false
        });

    return User;
};

export {
    User,
};

같이 DB나 table이 여러개일 때, 유동적으로 sequelize 모델을 가져올 수 있다.

 

 


  Sequelize로 만들어진 쿼리문에는 약간 좀 이상한게 있었다.

  보통 쿼리문에서 FROM 다음에 'schema'.'table' 이런식으로 나눠서 쿼리문을 만드는데 Sequelize는 'schema.table' 이렇게 한번에 만들어져서.. Sequelize 연결객체가 DB를 연결하고 있고, 스키마를 선택하고 있으면 당연히 오류가 발생했다.. schema.schema.table 이렇게 찾기 때문!!

그래서 github에 찾아보니 같은 Issue로 고생한사람들이 꽤 보였다. 아래는 링크다.

Github Sequlize Schema Issue

완벽한 해결책은 아니지만 dialect의 schemas를 true로 하면 해결된다.

MySQL에서만 발생함. 다른곳 소스코드를 다 뜯어보니 다 schemas는 true로 되어있음
const conn = new Sequelize(
  {
    host: host,
    username: Config.subdb.user,
    password: Config.subdb.password,
    dialect: "mysql",
    logging: process.env.NODE_ENV == "development" ? console.debug : false
  },
);

// @ts-ignore
conn.dialect.supports.schemas = true;

난 타입스크립트로 sequelize를 구현했고 eslint 적용을 해놔서 ts-ignore 어노테이션을 달아놨다.

이런식으로 하면 해결되긴 한다..