반응형
250x250
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Notice
Recent Posts
Today
Total
관리 메뉴

네이처리 노트

[Node.js] NPM mysql | cannot enqueue handshake after invoking quit | ER_HOST_NOT_PRIVILEGED: Host '127.0.0.1' is not allowed to connect to this MySQL server 본문

개발기록/Node.js

[Node.js] NPM mysql | cannot enqueue handshake after invoking quit | ER_HOST_NOT_PRIVILEGED: Host '127.0.0.1' is not allowed to connect to this MySQL server

네이처리 2022. 10. 1. 16:28
728x90
반응형

공부하면서 정리한 내용입니다

참고한 내용은 링크를 확인해주세요

 


 

 

📦 mysql

 

서버 및 데이터베이스 정보

let connectionInfo = {    
        
    host     : 'Server_IP', 
    port     : 'DB_connection_port',  // default 3306
    user     : 'DB_userID',
    password : 'DB_password',
    database : 'DB_name',
    multipleStatements : true,
    typeCast: true,            // true : SQL 결과값이 버퍼로 보여지는 것을 문자열로 변환
    dateStrings : true,        // true : UTC time으로 출력되는 경우, 문자열로 변환
};

파일에 DB정보 입력하는건 보안이슈로 대체할 방법이 필요하다.

👉🏻 환경변수에 저장하기, json 파일로 저장하기, NPM nopt 사용하기

 

 

데이터베이스 연결하기

프로젝트 내부에서  DB연결을 자유롭게 할 수 있도록 고안된 코드입니다.

다양한 방법으로 시도해 본것이라 기본적인 내용은 🔗NPM mysql 홈페이지를 참고해주세요.

1. ES6 이전 require 방식

var mysql = require('mysql');  

var dbconnection = {  
    init : function(connectionInfo){
        return mysql.createConnection(connectionInfo);
    },
    dbopen : function(con){
        con.connect(function(err){  // connect server
            if(err){
                console.error(" > mysql : connection error : " + err);
            }else{
                console.info(" > mysql : connection successfully.");
            }
        });
    }
};

module.exports = dbconnection; // 외부로 공유햘 서버커넥션API 내보내기

2. ES6 이후 import 방식

import { createConnection } from "mysql";

let db = {
    open: (connectionInfo)=>{
        const DBconn = createConnection(connectionInfo);
        // DBconn.connect(callback err); // connection duplication error!!
        return DBconn;
    },
    close: (eDBconn)=>{
        eDBconn.end((err)=>{
             if(err) console.log(err);
        })
    },
}

export default db;

3. global & promise 사용하기

import { createConnection } from "mysql";

global.db = {
    open: (connectionInfo)=>{
        const connection = createConnection(connectionInfo);
        return { 
            query (sql, args){ 
                return new Promise((res, rej)=>{
                    connection.query(sql, (err, rows)=> (err) ? rej(err) : res(rows));
                });
            }, 
            close (){ 
                return new Promise((res, rej)=>{
                    connection.end( err => (err) ? rej(err) : res() );
                });
            } 
        };
    }
}

//global사용하여 exports하지 않아도 됨

✅ 최종적으로 사용한 코드

import { createConnection } from "mysql";

export let db = {

    open: (connectionInfo)=>{
    	
        let connection = createConnection(connectionInfo); 
        
        // 다른페이지에서 실행시킬거라서 return 사용
        // 여기서 connection 실행하면 이중커넥션으로 오류발생

        return {
            query(sql, args){
                return new Promise((res, rej)=>{
                    connection.query(sql, (err, rows)=>{	//쿼리조회
                        (err)? rej(err) : res(rows);
                    });
                });
            },
            close(){
                return new Promise((res, rej)=>{
                    if(connection.state !== "disconnected"){  // 미연결상태 확인 (미연결상태에서 종료코드들어가면 오류메세지 발생함)
                        connection.end((err)=>{		//연결종료
                            if(err) rej(err);
                        });
                    }
                    res();
                });
            }
        }
    }
}

👩🏻‍💻외부에서 사용한 예시

더보기
// membership.js

import express from "express"; 
import { db } from "common/dbconnect.js";	// Mysql로 만든 DB API 가져옴
import { membership } from "common/dbTable.js";
import { Select, Where, Table } from "common/classQuery.js";	

let router = express.Router();

/*************************************************************************************
 * 
 *      @description 
 *      this is example that used db API
 * 
 *************************************************************************************/

router.post("/", async(request, response)=>{

    let responseData = {};

    const dbconn = db.open();	//DB연결

    try {
        
        const mTable = new Table(membership);
        
        let membershipData = [];

        // get Data
        let whereSeq = new Where(mTable).orderBy(mTable.seq).asc().getResult;
        let selectSeq = new Select("*").from(mTable).where(whereSeq).getResult;
        let result = await dbconn.query(selectSeq).catch((err)=>{ throw err; });	//DB검색 후 결과리턴

        if (result.length)
        {
            for(let each of result)
            {
                    let obj = {};

                    obj.tbl_key	= each.tbl_key;
                    obj.member_name	= each.member_name;
                    obj.member_code = each.member_code;

                    membershipData.push(obj);
            }
        }
        
        // success Data 
        responseData = {
            success: true,
            data : {"membership" : membershipData}
            }
        }; 

    } catch (error){
        // fail Data
        responseData = {
            success: false,
            data : error
        };

    } finally{
        dbconn.close().catch(err => console.log("db close error", err));	//DB연결해제
        response.json( responseData );
    }
});


export default router;

 

 

 

 

 

 

 

이슈

mysql 시간결과값이 다르게 노출됨. 9시간차이

실제 데이터 2021-05-14 17:33:35
mysql 출력  2021-05-14T08:33:35.000Z (UTC time)

해결방안
1. DB 데이터 정보입력하는 옵션에서 String으로 출력하게 가능

2. 🔗mysql에서 타임존 변경하기

 

 

Error 1

cannot enqueue handshake after invoking quit.

DB를 종료했는데, 초기화(createconnection)없이 접속을 시도해서 생긴 오류

const $DB = require(__dirname + '/config/database.js'); // DB
const $DBcon = $DB.init();     // <<<< 여기코드를

$exp.post('/test', upload.single(), function(request, response){
    const $DBcon = $DB.init();  // <<<< 이 곳으로 이동했더니 정상작동함
    $DB.dbopen($DBcon);
    $DBcon.query(sql, function (err, result) {
    	//something
    });
    $DBcon.end();
    response.send( 전송할값 );
}

 

 

Error 2

ER_HOST_NOT_PRIVILEGED: Host '127.0.0.1' is not allowed to connect to this MySQL server

DB정보 입력하는 부분에서 호스트를 domain.com에서 localhost로 변경했더니 발생한 오류

외부로 호출하는 것이 아니어서 localhost한건데 찾을 수 없다함

let connectionInfo = {    
    host     : 'domain.com',	// 이부분 
    port     : 'DB_connection_port', 
    user     : 'DB_userID',
    password : 'DB_password',
    database : 'DB_name',
};

서버관리해주는 cafe24에 문의했을 때

 | DB_name| localhost | DB_userID | 이렇게 넣었으니 시도해보라고함

안 됨 

 | DB_name| 127.0.0.1 | DB_userID | 이번에는 127.0.0.1 넣어줌

잘 됨

둘 다 같은건데 왜 안되는지 두명다 어리둥절 했던 상황 어쨋든 해결함

 

 

 

Reference

🔗MySQL and Promises

🔗Multiple Statements  (다중쿼리 처리방법)

🔗MySQL and async/await  (동기진행하는방법 / 다른방법은 mysql2 모듈사용하기)

 

 

 

 


728x90
반응형
Comments