express 환경에서 DB와 연결 시도 중 이런 에러를 만났다.
TypeORMError: Connection is not established with mysql database
at /Users/jominsu/Desktop/wecode/wecode_server/node_modules/typeorm/driver/mysql/MysqlDriver.js:734:22
at new Promise (<anonymous>)
at MysqlDriver.obtainMasterConnection (/Users/jominsu/Desktop/wecode/wecode_server/node_modules/typeorm/driver/mysql/MysqlDriver.js:720:16)
at MysqlQueryRunner.connect (/Users/jominsu/Desktop/wecode/wecode_server/node_modules/typeorm/driver/mysql/MysqlQueryRunner.js:59:18)
at /Users/jominsu/Desktop/wecode/wecode_server/node_modules/typeorm/driver/mysql/MysqlQueryRunner.js:145:55
at new Promise (<anonymous>)
at MysqlQueryRunner.query (/Users/jominsu/Desktop/wecode/wecode_server/node_modules/typeorm/driver/mysql/MysqlQueryRunner.js:143:16)
at DataSource.query (/Users/jominsu/Desktop/wecode/wecode_server/node_modules/typeorm/data-source/DataSource.js:345:42)
at totalSelect (/Users/jominsu/Desktop/wecode/wecode_server/services/threadService.js:31:42)
at Layer.handle [as handle_request] (/Users/jominsu/Desktop/wecode/wecode_server/node_modules/express/lib/router/layer.js:95:5)
Node.js v18.17.0
코드를 살펴보던 중 appDataSource를 받아오지 못한 이유로 에러가 났다고 생각했다.
threadService.js와 userService.js로 함수를 나눠서 분배했고 함수를 실행함에 있어 DB와의 연결이 필수가 되기 때문에 어떻게 해야 분리된 두 파일에서 사용할 수 있을까 고민됐다.🤔
📍 appDataSource
const { DataSource } = require("typeorm");
const appDataSource = new DataSource({
type: process.env.TYPEORM_CONNECTION,
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
});
appDataSource.initialize().then(() => {
console.log("데이터 소스가 초기화되었습니다");
});
📍 threadService.js
const insertPost = async (req, res) => {
const postContent = req.body.content;
const postUserId = req.body.user_id;
console.log(postContent);
console.log(postUserId);
const postData = await appDataSource.query(`
insert into threads (content , user_id) values ('${postContent}' , '${postUserId}')`);
console.log("typeorm return postData" + postData);
return res.status(201).json({ message: "post created" });
};
//2023-10-13 sql update
const totalSelect = async (req, res) => {
const selectData = await appDataSource.query(`
select threads.* ,users.nickname as name from threads join users on threads.user_id = users.id`);
console.log("typeorm return selectData" + selectData);
return res.status(200).json({
message: "post read",
data: selectData,
});
};
const userSelect = async (req, res) => {
const userId = req.body.user_id;
const selectData = await appDataSource.query(
`select t.content from users u join threads t on u.id = t.user_id where u.id = '${userId}'`
);
console.log("typeorm return selectData" + selectData);
return res.status(200).json({
message: "user post read",
data: selectData,
});
};
const postUpdate = async (req, res) => {
const userId = req.body.user_id;
const updateData = req.body.content;
const threadId = req.body.thread_id;
const updateElement = await appDataSource.query(
`update threads set content = '${updateData}' where user_id = '${userId}' and thread_id = '${threadId}'`
);
const selectElement = await appDataSource.query(`select * from threads`);
console.log(updateElement);
return res.status(200).json({
message: "posting update successfully",
data: selectElement,
});
};
const deletePost = async (req, res) => {
const userId = req.body.user_id;
const threadId = req.body.thread_id;
const delectElement = await appDataSource.query(
`delete from threads where user_id = '${userId}' and thread_id = '${threadId}' `
);
console.log(delectElement);
return res.status(200).json({ message: "delete post successfully" });
};
const insertLikes = async (req, res) => {
const userId = req.body.user_id;
const threadId = req.body.thread_id;
const heart = await appDataSource.query(
`insert into thread_likes (user_id, thread_id)
values ('${userId}' , '${threadId}')`
);
console.log(heart);
return res.status(200).json({ message: "insert heart successfully" });
};
module.exports = {
insertPost,
totalSelect,
userSelect,
postUpdate,
deletePost,
insertLikes,
appDataSource
}
📍 userService.js
// 1.회원가입 하는 함수 생성
const dotenv = require("dotenv");
dotenv.config();
const { DataSource } = require("typeorm");
const appDataSource = new DataSource({
type: process.env.TYPEORM_CONNECTION,
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
});
appDataSource.initialize().then(() => {
console.log("데이터 소스가 초기화되었습니다");
});
const signUp = async (req, res) => {
//1-1 request body로부터 사용자 정보 받아오기
const userNickName = req.body.nickname;
const userEmail = req.body.email;
const userPassword = req.body.password;
console.log("req userName: " + userNickName);
console.log("req userName: " + userEmail);
console.log("req userName: " + userPassword);
//1-2 받아온 정보를 DB에 저장함
//1-2-1 typeorm 설치 후 , appData
//1-2-2 SQL
const userData = await appDataSource.query(`
insert into users (nickname, email, password)
values ('${userNickName}', '${userEmail}', '${userPassword}')`);
//1-3 저장이 되었는지 확인하기
console.log("typeorm return userData" + userData);
//1-4 front에게 저장이 잘 되었다고 res 보내기
return res.status(201).json({ message: "SignUp successful" });
};
//2.Express app에 회원가입 하는 함수 연결
//2-1. HTTP method와 HTTP url 같이 설정하여 연결
module.exports = {
signUp,
appDataSource
};
두 모듈에서 함수를 받아와 server를 실행하는 test.js에서 실행해봤다.
📍 test.js
const http = require("http");
const express = require("express");
const {appDataSource} = require("./services/userService")
const { signUp } = require("./services/userService");
const {
insertPost,
totalSelect,
userSelect,
postUpdate,
deletePost,
insertLikes,
} = require("./services/threadService");
const app = express();
app.use(express.json());
// Health check function
app.get("/", async (req, res) => {
res.status(200).json({
message: "hello",
});
});
// Routes
app.post("/users/signUp", signUp);
app.post("/posts/posting", insertPost);
app.get("/posts/read", totalSelect);
app.get("/users/posts/read", userSelect);
app.patch("/posts/posting/update", postUpdate);
app.delete("/posts/posting/delete", deletePost);
app.post("/posts/posting/heart", insertLikes);
const server = http.createServer(app);
const start = async () => {
try {
server.listen(8000, () => console.log("Server is listening on 8000"));
appDataSource.initialize().then(() => {
console.log("Data Source has been initialized");
});
} catch (err) {
console.log(err);
}
};
start();
결과는 실패...😂
코드를 가만히 보다 느낀점은 어떻게 해야 두 모듈에 일정하게 appDataSource를 보내주고 test.js에서 받아 사용할 수 있을까 고민하게 됐고 require를 주목하게 됐다.
module.export로 내보내고 require로 받아올 수 있는걸 생각하다보니 그렇담 전혀다른 새로운 파일에 appDataSource를 저장하고 그 파일을 module.export로 threadService , userService , test 3개의 파일에 균일하게 보내줘야 겠다는 결론이 섰다.
📍 db.js
const dotenv = require("dotenv");
dotenv.config();
const { DataSource } = require("typeorm");
const appDataSource = new DataSource({
type: process.env.TYPEORM_CONNECTION,
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
});
appDataSource.initialize().then(() => {
console.log("데이터 소스가 초기화되었습니다");
});
module.exports = appDataSource;
📍 test.js
const appDataSource = require('./db')
const dotenv = require("dotenv");
dotenv.config();
const http = require("http");
const express = require("express");
const { signUp } = require("./services/userService");
const {
insertPost,
totalSelect,
userSelect,
postUpdate,
deletePost,
insertLikes,
} = require("./services/threadService");
const app = express();
app.use(express.json());
// Health check function
app.get("/", async (req, res) => {
res.status(200).json({
message: "hello",
});
});
// Routes
app.post("/users/signUp", signUp);
app.post("/posts/posting", insertPost);
app.get("/posts/read", totalSelect);
app.get("/users/posts/read", userSelect);
app.patch("/posts/posting/update", postUpdate);
app.delete("/posts/posting/delete", deletePost);
app.post("/posts/posting/heart", insertLikes);
const server = http.createServer(app);
const start = async () => {
try {
server.listen(8000, () => console.log("Server is listening on 8000"));
appDataSource.initialize().then(() => {
console.log("Data Source has been initialized");
});
} catch (err) {
console.log(err);
}
};
start();
📍 userService.js
const appDataSource = require('../db')
// 1.회원가입 하는 함수 생성
const signUp = async (req, res) => {
//1-1 request body로부터 사용자 정보 받아오기
const userNickName = req.body.nickname;
const userEmail = req.body.email;
const userPassword = req.body.password;
console.log("req userName: " + userNickName);
console.log("req userName: " + userEmail);
console.log("req userName: " + userPassword);
//1-2 받아온 정보를 DB에 저장함
//1-2-1 typeorm 설치 후 , appData
//1-2-2 SQL
const userData = await appDataSource.query(`
insert into users (nickname, email, password)
values ('${userNickName}', '${userEmail}', '${userPassword}')`);
//1-3 저장이 되었는지 확인하기
console.log("typeorm return userData" + userData);
//1-4 front에게 저장이 잘 되었다고 res 보내기
return res.status(201).json({ message: "SignUp successful" });
};
//2.Express app에 회원가입 하는 함수 연결
//2-1. HTTP method와 HTTP url 같이 설정하여 연결
module.exports = {
signUp,
};
📍 threadService.js
const appDataSource = require('../db')
const insertPost = async (req, res) => {
const postContent = req.body.content;
const postUserId = req.body.user_id;
console.log(postContent);
console.log(postUserId);
const postData = await appDataSource.query(`
insert into threads (content , user_id) values ('${postContent}' , '${postUserId}')`);
console.log("typeorm return postData" + postData);
return res.status(201).json({ message: "post created" });
};
//2023-10-13 sql update
const totalSelect = async (req, res) => {
const selectData = await appDataSource.query(`
select threads.* ,users.nickname as name from threads join users on threads.user_id = users.id`);
console.log("typeorm return selectData" + selectData);
return res.status(200).json({
message: "post read",
data: selectData,
});
};
const userSelect = async (req, res) => {
const userId = req.body.user_id;
const selectData = await appDataSource.query(
`select t.content from users u join threads t on u.id = t.user_id where u.id = '${userId}'`
);
console.log("typeorm return selectData" + selectData);
return res.status(200).json({
message: "user post read",
data: selectData,
});
};
const postUpdate = async (req, res) => {
const userId = req.body.user_id;
const updateData = req.body.content;
const threadId = req.body.thread_id;
const updateElement = await appDataSource.query(
`update threads set content = '${updateData}' where user_id = '${userId}' and thread_id = '${threadId}'`
);
const selectElement = await appDataSource.query(`select * from threads`);
console.log(updateElement);
return res.status(200).json({
message: "posting update successfully",
data: selectElement,
});
};
const deletePost = async (req, res) => {
const userId = req.body.user_id;
const threadId = req.body.thread_id;
const delectElement = await appDataSource.query(
`delete from threads where user_id = '${userId}' and thread_id = '${threadId}' `
);
console.log(delectElement);
return res.status(200).json({ message: "delete post successfully" });
};
const insertLikes = async (req, res) => {
const userId = req.body.user_id;
const threadId = req.body.thread_id;
const heart = await appDataSource.query(
`insert into thread_likes (user_id, thread_id)
values ('${userId}' , '${threadId}')`
);
console.log(heart);
return res.status(200).json({ message: "insert heart successfully" });
};
module.exports = {
insertPost,
totalSelect,
userSelect,
postUpdate,
deletePost,
insertLikes,
}
db와 관련된 코드를 새로운 파일에 작성해서 module.export를 보내니 결과는 성공이었다.
스크롤하는 시간은 굉장히 짧은 시간이였지만 오류를 발견하고 해결하는데에 2시간 정도의 시간을 소요했다.
혹시나 코딩 공부를 시작한지 얼마되지 않았다면 오류를 해결할때 빠르게 해결하는것도 좋겠지만 천천히 시간을 두고 고민하고 검색없이 해결해보는것을 추천한다.
오랜시간을 한가지 문제에 대해서 고민하고 해결방법을 찾다가 결국 해결하는 과정을 겪어보니 성취감을 가질 수 있던 좋은 경험이었다고 생각한다.