개인공부/TIL(Today I Learned)

TIL 88일차_ Sequelize 사용하기

soon327 2021. 4. 16. 23:54

sequelize의 메서드를 통해서 DB에 접근하고,
sequelize-cli를 설치하여, CLI에서 모델을 생성해주거나, 스키마 적용, 마이그레이션을 할 수 있다.

sequelize-cli init

npm install --save-dev sequelize-cli
npx sequelize-cli init

위 두 명령어를 실행하여, 마이그레이션에 필요한 폴더 4가지(config, models, migrations, seeders)를 생성해준다.

이후,
첫 모델을 생성해 주자!

CLI에서 간단한 명령어로 모델을 생성할 수 있다.
npx sequelize-cli model:generate --name url --attributes url:string,title:string,visits:integer

model:generate 커맨드를 사용하면 nameattributes 옵션이 required option으로 설정된다.
위의 명령어 결과,
url라는 이름의 모델과, 그 안에 url,title,visits라는 attribute가 타입설정과 함께 들어가게 된다.
이러한 설정들이 models폴더 안에 url.js파일이 생성되어 들어가게되는데,
주의할점은 시퀄라이즈에서는 기존에 models 폴더안에 있던 index.js만을 사용한다.
url.js는 url 모델의 설정을 변경하고자 할 때, 해당 파일의 설정을 직접바꿔 변경해준다.

//models/url.js
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class url extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  }
  url.init(
    {
      url: DataTypes.STRING,
      title: DataTypes.STRING,
      visits: { type: DataTypes.INTEGER, defaultValue: 0 }, //이처럼 다른 옵션들을 추가할 수 있다.
    },
    {
      sequelize,
      modelName: 'url',
    }
  );
  return url;
};

다른 model 예시

module.exports = (sequelize, Datatypes) => {
  const user = sequelize.define('user', {
    name: {
      type: Datatypes.STRING(20),
      allowNull: false,
      unique: true
    },
    age: {
      type: Datatypes.INTEGER.UNSIGNED,
      allowNull: false,
    },
    comment: {
      type: Datatypes.TEXT,
      allowNull: true,
    },
  }, {
    timestamps: true,
  });
};

이제 다음의 명령어를 실행하면,
마이그레이션되어, 생성한 User모델이 실제로 database에 table로 들어가게 된다.
npx sequelize-cli db:migrat


테이블간의 관계를 정의할때는 아래의 메소드를 쓴다.
1 : N

  • 1 -> N : hasMany
  • N -> 1 : belongsTo

1 : 1

  • 1 -> 1 : hasOne

N : M

  • N -> M : belongsToMany

sequelize-cli 없이 모델을 시퀄라이즈하는 방법과
1:N의 관계인 user와 comment모델이 있을 때 관계를 정의하는 방법은
models > index.js에 아래와 같이 작성하면 된다.

// model을 sequelize에 연결해주는 코드
db.User = require('./user')(sequelize, Sequelize);
db.Comment = require('./comment')(sequelize, Sequelize);


// model들 간의 관계를 정의해주는 코드
db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id'});
db.Comment.belongsTo(db.User, { foreignKey: 'commenter', sourceKey: 'id'})

sequelize query

시퀄라이즈는 객체와 데이터베이스 사이에서 서로를 매핑해주는 역할을 한다.
SQL문을 자바스크립트로 생성하는 형태이기 때문에 시퀄라이즈만의 방법을 따라야 한다.
시퀄라이즈 쿼리는 프로미스를 반환하기 때문에 then을 붙여 결과값을 받을 수 있다.
프로미스 형태이기 때문에 async / await 문법 역시 함께 사용할 수 있다.

create, select

const { User } = require('../models');


// create
User.create({
  name: 'ooeunz',
  age: '25',
  comment: '안녕하세요'
});


// select
User.findOne({});

User.findAll({});


// select column
User.findAll({
  attributes: ['name', 'comment'] // === SELECT name,comment FROM database.table;
});

조건달기

const { User, Sequelize: { Op } } = require('../models');

// 초과
User.findAll({
  attributes: ['name', 'comment'],
  where: {
    age: { [Op.gt]: 30 }
  }
})

// or
User.findAll({
  attributes: ['name', 'comment'],
  where: {
    [Op.or]: [{ age: {[Op.gt]: 25} }, { name: 홍길동 }]
  }
})

// order & limit
User.findAll({
  attributes: ['name', 'comment'],
  order: [['age', 'DESC']],
  limit: 1
})

위 코드에서 models에서 Sequelize: { Op } 객체를 함께 받아왔다.
Op객체에는 여러가지 활용 가능한 연산자들이 포함되어있다.

Op.gt(초과)
Op.gte(이상)
Op.lt(미만)
Op.lte(이하)
Op.ne(같지 않음)
Op.or(또는)
Op.in(배열 요소 중 하나)
Op.notIn(배열 요소와 모두 다름)
추가적으로 order와 limit과 같은 쿼리역시 수행할 수 있다.

수정, 삭제

// update
User.update({
  comment: '수정 내용'
}, {
  where: { id: 1}
});


// delete
User.destory({
  where: { id: 1}
});

Reference

Sequelize API Reference
윤자이 기술블로그