반응형
Associate와 관련해서 db를 설계를 안 해서 구글링해보다가 알게되서 쓰는 글이다.
Associate
Sequelize CLI를 통해 Model을 정의하고, Migration으로 스키마를 관리한다. RDBMS의 Table간의 관계를 Sequelize에서 Model간의 관계로 정의하는 것을 말한다.
모델 및 마이그레이션 생성
테이블을 두개 생성할 것이다. 유저가 있으면 이 유저가 리뷰를 할 때, 이에 대한 모델 정의와 마이그레이션을 생성하고자 한다.
// 유저
sequelize model:generate --name Write_user --attributes email:string,password:string,name:string
// 리뷰
sequelize model:generate --name Review --attributes users_id:integer,content:string
모델명은 복수가 아닌 단수를 사용하고, 첫 글자는 대문자를 권장한다.
이렇게 생성하면 models파일에 내가 생성한 모델이 생성되어 있다. 파일에 생성될 때는 소문자로 생성되고, migration파일에는 <timestamp>-create-<모델명>.js형식으로 생성된다.
// models/Write_user.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Write_user 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
}
}
Write_user.init({
email: DataTypes.STRING,
password: DataTypes.STRING,
name: DataTypes.STRING
}, {
sequelize,
modelName: 'Write_user',
});
return Write_user;
};
반응형
모델 관계 정의
예시인 write_user와 review테이블 간의 관계는 하나의 유저는 여러 개의 리뷰를 가질 수 있다. 하나의 리뷰는 하나의 유저에 속한다. 이에 따라 1 : N관계가 성립된다.
Sequelize에서는 관계를 정의하기 위하여 hasMany()와 belongsTo() 메소드를 지원한다.
- hasMany() : write_user는 여러 개의 리뷰를 가진다.
- belongsTo() : review는 하나의 유저에 속한다.
Options
- as : target 모델의 별명, 이후 include 시 쿼리 결과 값의 이름으로도 사용된다.
- foreignKey : 외래 키 정의. 생략 시 모델명 + Id 로 컬럼을 생성한다.
- onUpdate, onDelete : RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL 선택
관계 종류
1 : N 관계 이외에도 1 : 1 또는 N : M 관계를 정의할 수 있다.
models/ 내에 두 모델 파일에서 해당 메소드를 사용하여 관계를 정의한다. static associate(models) {}을 수정해야 한다.
// 1 : 1
hasOne();
belongsTo();
// 1 : N
hasMany();
belongsTo();
// N : M
belongsToMany();
// models/write_user.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Write_user extends Model {
static associate(models) {
this.hasMany(models.Review, {
as: "reviews",
foreignKey: "userId",
onDelete: "cascade",
});
}
}
Write_user.init({
email: DataTypes.STRING,
password: DataTypes.STRING,
name: DataTypes.STRING
}, {
sequelize,
modelName: 'Write_user',
});
return Write_user;
};
// models/review.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Review extends Model {
static associate(models) {
this.belongsTo(models.Write_user, {
as: "write_users",
foreignKey: "userId",
onDelete: "cascade",
});
}
}
Review.init({
users_id: DataTypes.INTEGER,
content: DataTypes.STRING
}, {
sequelize,
modelName: 'Review',
});
return Review;
};
//migrations/20220702040557-create-write-user.js
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Write_users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
name: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Write_users');
}
};
//migrations/20220702040557-create-review.js
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Reviews', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
users_id: {
type: Sequelize.INTEGER,
references: {
model: "write_user",
key: "id",
},
},
content: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Reviews');
}
};
모델과의 관계와 상관없이 데이터베이스를 만들어지는 것이 먼저 보고 싶다면
sequelize db:migrate
을 입력하면 데이터베이스가 만들어진 것을 볼 수 있다.
반응형