본문 바로가기

Nodejs/Sequelize

Nodejs Express + Sequelize 기본 셋팅(Postgresql)

반응형

Nodejs 의 ORM Sequelize 초기 셋팅을 위한 라이브러리 설치

// npm
$ npm i --save sequelize
$ npm i --save pg pg-hstore
$ npm i --save js-yaml

// yarn
$ yarn add sequelize
$ yarn add pg pg-hstore
$ yarn add js-yaml

// sequelize/index.js

const { Sequelize, Op, DataTypes } = require('sequelize');
const fs = require('fs');
const path = require('path');
const basename = path.basename(__filename);
const yaml = require('js-yaml');
const config =
    yaml.load(
        fs.readFileSync(path.join(__dirname, "..", "config", "config.yaml"), 'utf8')
    )[process.env.NODE_ENV || "development"];

const db = {};
const sequelize = new Sequelize(config.db);

const isDirCheck = file => fs.statSync(path.join(__dirname, file)).isDirectory();

/* sequelize model define */
fs.readdirSync(__dirname).filter((file) => {
    return (file.indexOf('.') !== 0)
        && (file !== basename)
        && (file.slice(-3) === '.js' || (isDirCheck(file)));
}).forEach((file) => {
    if (isDirCheck(file)) {
        fs.readdirSync(path.join(__dirname, file)).forEach(inFile => {
            const model = require(path.join(__dirname, file, inFile))(sequelize, DataTypes);
            db[model.name] = model;
        });
    } else {
        const model = require(path.join(__dirname, file))(sequelize, DataTypes);
        db[model.name] = model;
    }
});

Object.values(db).filter(model => model.hasOwnProperty('association'))
    .forEach(model => model['association'](db));

module.exports = {
    sequelize,
    db,
    Op,
}

시퀄라이즈 모델 디렉토리 내에 패키지 구분을 위해 디렉토리 체크 부분을 추가하였고,

DB 접속정보는 개발환경 및 배포 환경에 따라 구분하기 위해 yaml 파일로 설정파일을 작성하였다.

 

##conifg/config.yaml

---
context: "/"
project: sequelize-test
development:
  comm:
    nodePort: 8091
  db:
    database: 데이터베이스
    username: 유저명
    password: 패스워드
    host: 아이피
    port: 포트
    dialect: postgres
    operatorAliases: false
    quoteIdentifiers: false
    timezone: "+09:00"
    logQueryParameters: false
    logging: true

production:
  comm:
    nodePort: 3000
  db:
    database: 데이터베이스
    username: 유저명
    password: 패스워드
    host: 아이피
    port: 포트
    dialect: postgres
    operatorAliases: false
    quoteIdentifiers: false
    timezone: "+09:00"
    logQueryParameters: false
    logging: false

위 작성된 index.js 파일과 같은 디렉토리 내에 시퀄라이즈 모델을 만들어준다. 

 

// sequelize/systemLog.model.js
// sequelize model sample

module.exports = (database, dataType) => {
    const systemLog = database.define('systemLog', {
        id: { field: 'id', type: dataType.INTEGER, primaryKey: true, autoIncrement: true},
        type: { field: 'type', type: dataType.STRING, allowNull: false },
        requester: { field: 'requester', type: dataType.STRING, allowNull: false },
        ip: { field: 'ip', type: dataType.STRING, allowNull: false },
        url: { field: 'url', type: dataType.STRING, allowNull: false },
        name: { field: 'name', type: dataType.STRING, allowNull: true },
        method: { field: 'method', type: dataType.STRING, allowNull: true },
        createdAt: { field: "created_at", type: dataType.DATE }, // 등록일 컬럼명 재정의
        updatedAt: { field: "updated_at", type: dataType.DATE }, // 수정일 컬럼명 재정의
    }, {
        classMethod: {},
        tableName: 'th_system_log', // 실제 테이블명
        underscore: true, // 카멜케이스 여부
        timestamps: true // 등록일, 수정일
    });

    return systemLog;
}

여기서 timestamps 를 true 로 만들면, 등록일 수정일이 createdat, updatedat 으로 만들어지므로, 모델 정의 부분에서 컬럼명을 재정의 하기위해 추가하였다.

디렉토리 내에 모델들도 생성되는 확인하기 위해 샘플 모델을 test1.model.js  ,  test2.model.js 도 추가하였다.

 

sequelize model

 

이 후, httpServer를 listen 하기 전에 테이블을 생성하는 구문을 추가해주면 된다.

// server.js

const app = require('./app');
const { sequelize } = require('./sequelize');
const http = require('http');
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

const commConfig =
    yaml.load(fs.readFileSync(path.join(__dirname, 'config', 'config.yaml'), 'utf8'));
const config = commConfig[process.env.NODE_ENV || "development"];

const PORT = config.comm.nodePort || 8080;
(async () => {
    try {
        await sequelize.authenticate();
        try {
            await sequelize.sync({ force: false });
            console.log(`✓ DB connection success.`);
            console.log(`  Press CTRL-C to stop\n`);
        } catch (err) {
            console.error(`✗ DB connection error. Please make sure DB is running.`);
            console.error(err.message);
            process.exit();
        }
        console.log(`Database connection OK!`);

        const httpServer = http.createServer(app);
        httpServer.listen(PORT, (err) => {
            if (err) {
                console.error(`Express Server has failed on port: ${PORT}`);
                throw err;
            }
            console.log(`Express server has started on port ${PORT}`);

            if (process.send) {
                process.send('ready');
            }
        });
    } catch (err) {
        console.error('Unable to connect to the database:');
        console.error(err.message);
        process.exit(1);
    }
})();

sync 의 force: false => 테이블이 이미 존재 할 때 테이블 생성을 하지 않는다.

          force: true => 테이블을 drop 후 create 한다.

 

전체 폴더 구조

디렉토리 구조

 

pgAdmin 에서 테이블이 생성된 것을 확인할 수 있다.

생성된 DB Table

 

https://github.com/sbjang123456/nodejs-sequelize-base

 

sbjang123456/nodejs-sequelize-base

Sequelize 초기 구축. Contribute to sbjang123456/nodejs-sequelize-base development by creating an account on GitHub.

github.com

 

반응형