티스토리 뷰

용도

database를 연결해 table들의 model을 생성해주는 library.

sequelize 사용 시 model 정보가 필요하므로 꼭 필요한 기능이다.

sequelize-auto: https://github.com/sequelize/sequelize-auto

실습

CLI로도 생성할 수 있지만 js로도 작성 가능하다. 재활용이나 수정 측면에서 용이하므로 js로

작성하기로 했다.

Programmatic API

https://github.com/sequelize/sequelize-auto?tab=readme-ov-file#programmatic-api

사전 설치

postgres DB에서 가져와야 하므로 아래 패키지를 설치해준다.

npm i -D sequelize pg pg-hstore

 다른 DB일 경우 각자 DB에 맞게 사전 설치를 진행한다.

사전설치 정보: https://github.com/sequelize/sequelize-auto?tab=readme-ov-file#prerequisites

generate-models.js

const path = require('path')
const fs = require('fs')

const { SequelizeAuto } = require('sequelize-auto')

// const dbInfo = config.database.mariadb
const dbConfig = {
    host: 'localhost',
    port: 5432,
    username: 'postgres',
    password: 'postgres1!',
    database: 'postgres',
    dialect: 'postgres',
    tables: ['UserInfo'] // 최소 예제를 위해 테이블 하나만
}

const sequelizeAuto = new SequelizeAuto(
    dbConfig.database,
    dbConfig.username,
    dbConfig.password,
    {
        host: dbConfig.host,
        port: dbConfig.port,
        dialect: dbConfig.dialect,
        directory: './models',
    }
)

sequelizeAuto.run()
node generate-models.js

생성된 파일들이다.

지정한 table의 model과 model instance를 생성해주는 init-models.js 를 확인할 수 있다.

init-models.js 코드를 확인해보자.

 

models/init-models.js

var DataTypes = require('sequelize').DataTypes
var _UserInfo = require('./UserInfo')

function initModels(sequelize) {
    var UserInfo = _UserInfo(sequelize, DataTypes)

    return {
        UserInfo,
    }
}
module.exports = initModels
module.exports.initModels = initModels
module.exports.default = initModels

init-models.js 는 위와 같이 sequelize instance를 이용해 생성된 Model 인스턴스를 생성한다.

우리는 initModels 함수에 sequelize 인스턴스 정보만 넘겨주면 된다. 예제는 아래와 같다.

init-models를 통해서 model instance를 생성하는 예제이다.

 

models/index.js

const initModels = require('./init-models')
// sequelize 생성
const sequelize = new Sequelize(...)
// model isntance 생성
const models = initModels(sequelize)

이제 위의 생성된 models 인스턴스를 사용하면 된다. 😆

부록

JSDoc 추가

현재 프로젝트는 JS 프로젝트 이므로 model을 정의해도 자동완성 기능을 사용할 수 없다.

이러한 점을 보완하기 위해 JSDoc을 통해 타입추론이 되도록 설정해보자.

JSDoc 작성을 위해서는 일단 Table에 대한 Interface 정보가 정의된 d.ts 파일이 필요하다.

DB를 통해 interface 생성하기 참조

 

위와 같이 models.d.ts 파일을 생성한 뒤, JSDoc을 추가하여 sequelize model을 생성하자.

 

generate-model.js

const path = require('path')
const fs = require('fs')

const { SequelizeAuto } = require('sequelize-auto')

// 생략
const dbConfig = {
    ...
}

const sequelizeAuto = new SequelizeAuto(
    ...
)

// 실행후 jsdoc 추가
sequelizeAuto.run().then(() => {
    const path = require('path')
	
		// 현재 디렉토리 파일 목록 추출
    const files = fs.readdirSync(path.join(__dirname, './models'), {
        withFileTypes: true,
    })
    const exceptList = ['index.js', 'init-models.js']
		
    files.forEach(async (file) => {
        if (exceptList.includes(file.name)) return
				
				// JsDoc 추가
        addJsDoc(file)
    })
})

/**
 * jsdoc 정보 추가
 * table interface 정보 intersection
 * @param {fs.Dirent} file
 */
function addJsDoc(file) {
    const modelPath = path.join(file.path, file.name)

    const data = fs.readFileSync(modelPath, { encoding: 'utf-8' })

    const modelName = file.name.split('.')[0]
    const result = data.replace(
        /module.exports = function\\(sequelize, DataTypes\\)/g,
        `/**
        * @param {import('sequelize').Sequelize} sequelize
        * @return {import('sequelize').ModelCtor<import('sequelize').Model<${modelName}, ${modelName}>>}
        */
        module.exports = function (sequelize, DataTypes)`
    )

    fs.writeFileSync(modelPath, result, 'utf-8')
}

 

UserInfo.js

const Sequelize = require('sequelize')
/**
 * @param {import('sequelize').Sequelize} sequelize
 * @return {import('sequelize').ModelCtor<import('sequelize').Model<UserInfo, UserInfo>>}
 */
module.exports = function (sequelize, DataTypes) {
    return sequelize.define(
        'UserInfo',
        {
	        ...
        }
}

위와 같이 주석이 추가되어서 model이 만들어졌다.

이로서 해당 model을 사용할 때 타입추론의 도움을 받아 자동완성을 사용할 수 있게 된다. 😆

댓글