본문 바로가기
TIL

2020.09.03 sequelize mvc 스프린트 처음부터 구현하기

by 시계의온도 2020. 9. 3.

[내일 공부할것] --> 화요일에 세운 계획 

controller 구현, sprint완성하기. 일단 테스트 통과 후 처음부터 재작성 하기. :완료

오피스 아워. : 로그인 인증 내용 강의 들음

toy-30 번 풀기.  : 못함.. 

 

+) sequelize 사용 MVC 스프린트 다시 처음부터 코드 작성해서 제출하기 

 

[실제 한것]

공부시간: 7시간 정도. 

 

sequelize 설치. 

//터미널
$ npm install --save sequelize

마이그레이션을 하기 위한 cli 설치 

//터미널
npm install --save-dev sequelize-cli

프로젝트 bootstrapping 

//터미널
npx sequelize-cli init

 

터미널에 mysql을 열어서 데이터베이스를 만들어 주기. 

//터미널
mysql -u root -p

mysql> create database sprintMVC ;
//데이터베이스 생성 

Table Plus GUI 에서 데이터베이스 확인하기  -> 생성확인됨. 

 

config 설정 변경 

{
  "development": {
    "username": "root",
    "password": "---",//내 mysql접속 비밀번호 
    "database": "sprintMVC",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": "---",//내 mysql접속 비밀번호 
    "database": "sprintMVC",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": "---",//내 mysql접속 비밀번호 
    "database": "sprintMVC",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

 

models 하위에 url.js 파일 생성 후 모델 작성. 함수로 작성해준다. 

//cli를 통해서 코드를 만들면, 아래와 같은 구조로 생성된다. 
//이런 구조로 모델을 작성해야, sequelize에서 사용할 수 있는데, 원리는 좀더 공부해봐야겠다. 
//models/index.js 에서 파일을 읽어오면서, 적용되는걸로 추정..된다. 


const { Model } = require('sequelize');

module.exports = (sequelize, DataTypes) => {
    class Url extends Model { }

    Url.init({
        url:DataTypes.STRING,
        title:DataTypes.STRING,
        visits:{
            type:DataTypes.INTEGER, 
            defaultValue:0 }
    }, {
        sequelize, // 데이터베이스 connection
        modelName: 'Url'
    });
    return Url;
}

 

마이그레이션을 진행해야 DB에 반영된다. 모델코드를 따로 작성했으므로, migration skeleton 코드작성. 

 

//터미널
npx sequelize-cli migration:generate --name 내가 넣고 싶은 이름 migration-skeleton

 

명령어를 실행하면 migration 디렉토리에 이런 코드가 생성된다. 

 

'use strict';

module.exports = {
  up: async (queryInterface, Sequelize) => {
    /**
     * Add altering commands here.
     *
     * Example:
     * await queryInterface.createTable('users', { id: Sequelize.INTEGER });
     */
  },

  down: async (queryInterface, Sequelize) => {
    /**
     * Add reverting commands here.
     *
     * Example:
     * await queryInterface.dropTable('users');
     */
  }
};

 

작성해주기.

 

module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('urls',
      {
        url: Sequelize.STRING,
        title: Sequelize.STRING,
        visits: {
          type: Sequelize.INTEGER,
          defaultValue: 0
        }
      })
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('urls');
  }
};

 

마이그레이션 해주기!

 

//터미널
npx sequelize-cli db:migrate

 

터미널에 이런 안내메세지가 뜨면서 테이블이 생성된걸 볼 수 있다. sequelizeMeta도 생성된다. 

 

Loaded configuration file "config/config.json".
Using environment "development".
== 20200903103539-url: migrating =======
== 20200903103539-url: migrated (0.017s)

 

cli 에서 자동으로 생성해주면, 터미널에 치기 번거롭다는 단점이 있지만 아래와 같은 장점이 있다.

레퍼런스: https://victorydntmd.tistory.com/27

  • 테이블 이름이 복수형으로 변경
  • 자동으로 id, createAt, updateAt 3개의 필드를 생성
  • migration 파일을 생성

cli로 생성해주지 않았으므로..ㅠㅠ 직접 작성해주어야 한다. 마이그레이션 파일을 수정하고 다시 마이그레이션을 해주더라도, 새로운 내용이 반영된 테이블이 생성되지 않는데, 이미 기존에 테이블이 동일한 내용으로 생성되서 그런것 같다. 

 

//터미널
npx sequelize-cli db:migrate:undo

 

즉, 여태까지 해본결과 마이그레이션을 해주면 최신 상태로 업댓해주지 않고, undo를 했다가 다시 npx sequelize-cli db:migrate 를 해주면 mysql에서 테이블 칼럼이 업데이트 된걸 볼 수 있다. 

 

테스트케이스를 돌려보면, 자꾸 int(11)이 int로 되야 한다고 하는데 최신버전인 6.3.5 에서도 int(11)로 찍히는 이유를 나는 모르겠다.. 헬프데스크에 올려봐야겠다...

 

이제 MVC중 controllers작성 후 routing하기. 테스트케이스를 잘 보고 똑같은 명칭의 경로로 파일을 만들어야 한다; 

스프린트를 하면서 제일 많이 본 에러는 

 

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

 

인데 asnyc , await , res end까지 완성하면 해결된다. 구글링 해보니 모카에서 내는 에러다. 

라우터 코드 구현. 그리고 컨트롤러의 get을 구현하던 중 findAll()을 하면 select와 동일하게 데이터 목록 전부를 배열의 형태로 불러올 수 있다는 걸 배웠다. 추가로 res.status().json() 형식으로 사용할 수도 있다는 걸 알았다. 

 

res.json() 레퍼런스

https://haeguri.github.io/2018/12/30/compare-response-json-send-func/

 

sequelize의 메소드를 사용하기 위해서는 async 함수로 get과 post함수를 선언해주어야한다. 이후 주어진 utils.js파일을 이용해서, post함수를 작성해야한다. 혹시 이글을 보시는 분들이 정답을 스포(?)당할까봐 컨트롤러 관련 코드는 작성하지 않기로. 

 

이 코드를 이해하기 위해서 request에 대해서 다시 공부했다. 

https://www.npmjs.com/package/request

 

request

Simplified HTTP request client.

www.npmjs.com

당황스러운 것은, findOrCreate 를 어떻게 넣어서 title을 뽑아내야..하나 싶은 문제였는데, 레퍼런스를 꼼꼼히 보니 리턴값에 불리언이 있었다. 

 

https://sequelize.org/master/class/lib/model.js~Model.html#static-method-findOrCreate

 

즉, 프로미스방식으로 리턴하되 모델과 불리언을 리턴한다! 그래서 실질적으로 해당 배열의 값은 2개가 되니 인자를 두개로 나눠서 배열의 구조분해 할당 방식으로 받아오면, 각 변수에 접근해서 문제를 해결할 수 있는 것이다. 이거참, 알고보니 보는거지 허허허헣.

그리고 헷갈리는 부분은, 기존에 값이 있으면 false / 값이 없으면 true를 리턴하는 것이다. 아니..반대가 맞지않나..? 

아마도 기존에 값이 없으면 만들꺼니까 true! 이런식인가.. (추측..) 

 

마지막으로 redirect 까지 구현하면 과제는 끝난다. 리다이렉트 될때마다 visits를 1씩 업데이트하는게 목적인데, 이 과정에서 sementic url 방식이 사용된다. 해당 방식은, 쿼리스트링을 통해서 하는것에 비해서 url을 깔끔해 보이게 만들어주는 방법으로, 

 

req.params를 통해 값을 받아올수 있다. req.params를 하면 {id: '1'} 처럼 객체를 리턴해준다. 

 

레퍼런스

https://velog.io/@nawnoes/Express-url-%EC%8A%A4%ED%8A%B8%EB%A7%81%EC%9D%84-%ED%86%B5%ED%95%9C-%EC%A0%95%EB%B3%B4%EC%A0%84%EB%8B%AC

 

Express url 스트링을 통한 정보전달

위와 같이 쿼리 스트링을 사용하고 싶은경우. req.query를 사용한다. 복수의 쿼리스트링을 가져오는 것도 가능: path 방식을 통한 url의 경우 params를 통해서 값을 가져올 수 있다.깔끔한 URL을 유지하�

velog.io

https://wayhome25.github.io/nodejs/2017/02/18/nodejs-11-express-query-string/

 

Express-URL을 이용한 정보의 전달 - 쿼리스트링 · 초보몽키의 개발공부로그

동적인 파일을 통해서 (app.js 에 직접 작성) 쿼리스트링 사용에 대해 살펴본다.

wayhome25.github.io

 

또 여기서 알게 된점은

 

await urlModel.findOne().then((data)=>{return }).then(res.redirect)

 

같이 await를 사용하더라도 .then을 통해서 연속해서 사용할 수 있다는점! 이다. await로 받아와도 체이닝 가능. 흠.. 프로미스 부분.. 진짜 못해도 30시간쯤은 쓴 것 같은데 매번 왜 이리 새로워;;

 

그리고 res.redirect는 express에서 지원하는 기능으로, 해당 url로 보내준다! 

 

길고 긴 스프린트를 처음부터 되짚어 가며 마무리하였다. 다음은 솔로 프로그래밍으로 구현하는 것이라고 하니, 해보면 더 잘 이해할 수 있을 것 같다. 그리고.. sequelize... 얼마나 현업에서 유용한지 모르겠지만 지금은 sql 쿼리 짜는게 더 쉬운거 같은데.. ㅠㅠ 

 

휘발성이라서 지금 생각은 또 아리아리 하게 나지만. 이번 스프린트가 유독 어렵긴 했지만, 한번 했던걸 되짚어 가는데도 계속 버벅 거렸다. 앞으로 복습을 누진적으로 꼭 해야겠다. 

 

[내일 할 것]

toy - 30 번 풀기 , 블로그에 리뷰하기

toy - 31 번 풀기 , 블로그에 리뷰하기 

인증(authentication) 스프린트 진행. 어차피 이번주는 솔로 프로그래밍이라고 하니 후딱 해버리자! 코테공부를 거의 못해서 

9/12일에 카카오 코테때 분명 떨어지겠지.. ㅠㅠ 사실 면접가도 지식이 너무 낮아서 쫄리긴한다. 

 

어차피 늦는거, 일과 병행하고 있으니 조급증 내지 말고 꾸준히 하자! 

(이직이라도 했으면 마음이 편할텐데.. ㅠㅠ) 

 

오늘도 고생했음 나자신!

'TIL' 카테고리의 다른 글

2020.09.09  (0) 2020.09.10
2020.09.06  (0) 2020.09.07
2020.09.05 Session 과 Cookie  (0) 2020.09.05
2020.09.04  (0) 2020.09.05
2020.09.01  (0) 2020.09.02

댓글