Commit 541c4207 authored by KangMin An's avatar KangMin An
Browse files

Create : DB 변경에 따른 디렉토리 생성 및 수정.

parent 451af32e
...@@ -30,7 +30,10 @@ ...@@ -30,7 +30,10 @@
"mysql2": "^2.2.5", "mysql2": "^2.2.5",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"node-schedule": "^2.0.0", "node-schedule": "^2.0.0",
"pug": "^3.0.0" "pg": "^8.6.0",
"pg-hstore": "^2.3.4",
"pug": "^3.0.0",
"sequelize": "^6.6.5"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^2.0.4" "nodemon": "^2.0.4"
......
import mysql from "mysql2/promise";
import dotenv from "dotenv";
dotenv.config();
// MySQL Config
const db_config = {
host: process.env.MYSQL_HOST || "localhost",
user: process.env.MYSQL_USER || "root",
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE || "EUE",
connectionLimit: 5,
};
// Creation of MySQL Pool, and Export
export const pool = mysql.createPool(db_config);
// Messages for Data Base.
export const dbMSG = {
connection_err: "DB Connection Error.",
query_success: "DB Query Success.",
query_err: "DB Querry Error.",
};
/*
# EUE Server Database Schema
- DataBase : PostgreSQL
- 실제 서버 동작시 Sequelize가 models 디렉토리의 모델들에 따라 테이블을 생성합니다. 따라서 해당 SQL파일은 참고용으로 사용합니다.
1. LOC_DO
- 행정구역 도/특별시/특별자치시 이름과 코드 저장
- LOCSIGUNGU와 LOC_EMD에 참조됨
2. LOC_SGG
- 행정구역 시/군/구 이름과 코드 저장
- LOC_DO를 참조
- LOC_EMD에 참조됨
3. LOC_EMD
- 행정구역 읍/면/동 이름과 코드
- LOC_DO와 LOC_SGG를 참조
- USERS와 WEATHER_OUT에 참조됨
4. USERS
- 사용자 ID, PassWord, 거주지역코드
- LOC_EMD를 참조
5. WEATHER_IN
- 사용자 ID, 수집 날짜 및 시간, 온도, 습도, 광도
- USERS와 LOC_EMD 참조
6. WEATHER_OUT
- 지역 코드, 수집 날짜 및 시간, 온도, 습도, 기압, 풍속
- LOC_EMD 참조
*/
CREATE TABLE DOE
(
CODE INT NOT NULL,
NAME_DO VARCHAR(20) NOT NULL,
PRIMARY KEY(CODE_DO)
);
CREATE TABLE SGG
(
CODE INT NOT NULL,
CODE_DO INT NOT NULL,
NAME_SGG VARCHAR(20) NOT NULL,
PRIMARY KEY(CODE),
FOREIGN KEY(CODE_DO) REFERENCES DO(CODE) ON UPDATE CASCADE ON DELETE RESTRICT
);
CREATE TABLE EMD
(
CODE INT NOT NULL,
CODE_DO INT NOT NULL,
CODE_SGG INT NOT NULL,
NAME_EMD VARCHAR(20) NOT NULL,
PRIMARY KEY(CODE),
FOREIGN KEY(CODE_DO) REFERENCES DO(CODE) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY(CODE_SGG) REFERENCES SGG(CODE) ON UPDATE CASCADE ON DELETE RESTRICT
);
CREATE TABLE USERS
(
EMAIL VARCHAR(320) UNIQUE NOT NULL,
PW VARCHAR(20) NOT NULL,
LOC_CODE INT NOT NULL,
PRIMARY KEY(EMAIL),
FOREIGN KEY(LOC_CODE) REFERENCES EMD(CODE) ON UPDATE CASCADE ON DELETE RESTRICT
);
CREATE TABLE WEATHER_IN
(
HOST VARCHAR(320) NOT NULL,
COLLECTED_AT TIMESTAMP NOT NULL,
TEMP FLOAT DEFAULT 0,
HUMI FLOAT DEFAULT 0,
LIGHTS FLOAT DEFAULT 0,
PRIMARY KEY(EMAIL,COLLECTED_AT),
FOREIGN KEY(EMAIL) REFERENCES USERS(EMAIL) ON UPDATE CASCADE ON DELETE RESTRICT
);
CREATE TABLE WEATHER_OUT
(
LOC_CODE INT NOT NULL,
COLLECTED_AT TIMESTAMP NOT NULL,
TEMP FLOAT DEFAULT 0,
HUMI FLOAT DEFAULT 0,
PRESS FLOAT DEFAULT 0,
WIND_SPEED FLOAT DEFAULT 0,
PRIMARY KEY(LOC_CODE, COLLECTED_AT),
FOREIGN KEY(LOC_CODE) REFERENCES EMD(CODE) ON UPDATE CASCADE ON DELETE RESTRICT
);
\ No newline at end of file
import Sequelize from "sequelize";
import dotenv from "dotenv";
import Doe from "../models/doe";
import Sgg from "../models/sgg";
import Emd from "../models/emd";
import User from "../models/user";
import Weather_in from "../models/weather_in";
import Weather_out from "../models/weather_out";
dotenv.config();
const envs = process.env;
// DB의 정보를 모두 담고 있는 객체 생성
const db = {};
// PostgreSQL과 연결된 Sequelize 객체 생성
const sequelize = new Sequelize(
envs.DB_DATABASE,
envs.DB_USER,
envs.DB_PASSWORD,
{
host: envs.DB_HOST,
dialect: "postgres",
}
);
// db 객체에 값 입력
db.sequelize = sequelize;
// model들 생성
db.Doe = Doe;
Doe.init(sequelize);
db.Sgg = Sgg;
Sgg.init(sequelize);
db.Emd = Emd;
Emd.init(sequelize);
db.User = User;
User.init(sequelize);
db.Weather_in = Weather_in;
Weather_in.init(sequelize);
db.Weather_out = Weather_out;
Weather_out.init(sequelize);
// model들 간에 Association 생성
Doe.associate(db);
Sgg.associate(db);
Emd.associate(db);
User.associate(db);
Weather_in.associate(db);
Weather_out.associate(db);
// Messages for Data Base.
const msg = {
connection_err: "DB Connection Error.",
query_success: "DB Query Success.",
query_err: "DB Querry Error.",
};
db.msg = msg;
export default db;
import fs from "fs";
// import mysql from "mysql";
import Sequelize from "sequelize";
import dotenv from "dotenv";
dotenv.config();
const envs = process.env;
const sequelize = new Sequelize(
envs.DB_DATABASE,
envs.DB_USER,
envs.DB_PASSWORD,
{
host: envs.DB_HOST,
dialect: "postgres",
}
);
const checkCONN = async () => {
try {
await sequelize.authenticate();
console.log("Connection has been established successfully.");
sequelize.close();
} catch (error) {
console.error("Unable to connect to the database:", error);
}
};
checkCONN();
// // DB Connection
// const db = mysql.createConnection({
// host: process.env.MYSQL_HOST || "localhost",
// user: process.env.MYSQL_USER || "root",
// password: process.env.MYSQL_PASSWORD,
// database: process.env.MYSQL_DATABASE || "EUE",
// });
// const inputDo = (code, name) => {
// name = name.replace(/\s/g, "");
// let q = `INSERT INTO LOCDO (CODE,DONAME) VALUES (${code},'${name}');`;
// db.query(q, (err, result) => {
// if (err) {
// console.log(err);
// return;
// }
// console.log("Result : " + result);
// });
// };
// const inputSi = (code, name, doCode) => {
// name = name.replace(/\s/g, "");
// let q = `INSERT INTO LOCSIGUNGU (CODE,DOCODE,SGGNAME) VALUES (${code},${doCode},'${name}');`;
// db.query(q, (err, result) => {
// if (err) {
// console.log(err);
// return;
// }
// console.log("Result : " + result);
// });
// };
// const inputDong = (code, name, doCode, siCode) => {
// name = name.replace(/\s/g, "");
// let q = `INSERT INTO LOCINFO (CODE,DOCODE,SGGCODE,EMDNAME) VALUES (${code},${doCode},${siCode},'${name}');`;
// db.query(q, (err, result) => {
// if (err) {
// console.log(err);
// return;
// }
// console.log("Result : " + result);
// });
// };
// const setDB = () => {
// // DB Connect
// db.connect((err) => {
// if (err) {
// console.log(err);
// return;
// }
// console.log("connected as id" + db.threadId);
// });
// // File Read
// let originData = fs.readFileSync("data/admAddressCode.csv", "utf8");
// // Separate Data & Input Data
// let sepData = originData.split("\r\n");
// let setDoCode = new Set();
// let setSiCode = new Set();
// sepData.forEach((line) => {
// line = line.replace(/\s/g, "");
// let addr = line.split(",");
// const doCode = Number(addr[0]);
// if (!setDoCode.has(doCode)) {
// const doName = addr[1];
// inputDo(doCode, doName);
// setDoCode.add(doCode);
// }
// const siCode = Number(addr[2]);
// if (!setSiCode.has(siCode)) {
// const siName = addr[3];
// inputSi(siCode, siName, doCode);
// setSiCode.add(siCode);
// }
// const dongCode = Number(addr[4]);
// const dongName = addr[5];
// inputDong(dongCode, dongName, doCode, siCode);
// });
// // Connection Close
// db.end();
// };
// setDB();
import app from "./app"; import app from "./app";
import dotenv from "dotenv"; import dotenv from "dotenv";
import "./schedules"; // 매일 자정 데이터 처리 import "./schedules"; // 매일 자정 데이터 처리
import db from "./db/index";
dotenv.config(); dotenv.config();
...@@ -10,4 +11,14 @@ const handleListening = () => { ...@@ -10,4 +11,14 @@ const handleListening = () => {
console.log(`✅ Listening on : http://localhost:${PORT}`); console.log(`✅ Listening on : http://localhost:${PORT}`);
}; };
// DB 연결
db.sequelize
.sync({ force: false })
.then(() => {
console.log("DB Connect Suceecs!");
})
.catch((err) => {
console.log(err);
});
app.listen(PORT, handleListening); app.listen(PORT, handleListening);
/*
# DB의 Do(도) 테이블의 모델입니다.
- 도 코드와 이름 정보를 저장합니다.
*/
import { DataTypes, Model } from "sequelize";
export class Doe extends Model {
static init(sequelize) {
return super.init(
{
code: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
},
name_do: {
type: DataTypes.STRING(20),
allowNull: false,
},
},
{
sequelize,
timestamps: false,
paranoid: false,
}
);
}
static associate(db) {
// 모델이 참조되는 테이블 설정
db.Doe.hasMany(db.Sgg, {
foreignKey: "code_do",
sourceKey: "code",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
db.Doe.hasMany(db.Emd, {
foreignKey: "code_do",
sourceKey: "code",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
export default Doe;
/*
# DB의 EMD(읍면동) 테이블의 모델입니다.
- 읍/면/동의 코드와 이름을 저장합니다.
- 외래키로 Do 코드와 SGG 코드를 사용합니다.
*/
import { DataTypes, Model } from "sequelize";
export class Emd extends Model {
static init(sequelize) {
return super.init(
{
code: {
type: DataTypes.INTEGER,
allowNull: true,
primaryKey: true,
},
name_emd: {
type: DataTypes.STRING(20),
allowNull: false,
},
},
{
sequelize,
timestamps: false,
paranoid: false,
}
);
}
static associate(db) {
// 모델이 참조하는 테이블
db.Emd.belongsTo(db.Doe, {
foreignKey: "code_do",
targetKey: "code",
});
db.Emd.belongsTo(db.Sgg, {
foreignKey: "code_sgg",
targetKey: "code",
});
// 모델이 참조되는 테이블
db.Emd.hasMany(db.User, {
foreignKey: "loc_code",
sourceKey: "code",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
db.Emd.hasMany(db.Weather_out, {
foreignKey: "loc_code",
sourceKey: "code",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
export default Emd;
/*
# DB의 SGG(시군구) 테이블의 모델입니다.
- 시/군/구의 코드와 이름을 저장합니다.
- 외래키로 Do 코드를 사용합니다.
*/
import { DataTypes, Model } from "sequelize";
export class Sgg extends Model {
static init(sequelize) {
return super.init(
{
code: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
},
name_sgg: {
type: DataTypes.STRING(20),
allowNull: false,
},
},
{
sequelize,
timestamps: false,
paranoid: false,
}
);
}
static associate(db) {
// 모델이 참조하는 테이블
db.Sgg.belongsTo(db.Doe, {
foreignKey: "code_do",
targetKey: "code",
});
// 모델이 참조되는 테이블
db.Sgg.hasMany(db.Emd, {
foreignKey: "code_sgg",
sourceKey: "code",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
export default Sgg;
/*
# DB의 Users 테이블의 모델입니다.
- email과 비밀번호를 저장합니다.
- 외래키로 EMD 코드를 사용합니다.
*/
import { DataTypes, Model } from "sequelize";
export class User extends Model {
static init(sequelize) {
return super.init(
{
email: {
type: DataTypes.STRING(320),
allowNull: false,
primaryKey: true,
},
pw: {
type: DataTypes.STRING(20),
allowNull: false,
},
},
{
sequelize,
timestamps: false,
paranoid: false,
}
);
}
static associate(db) {
// 모델이 참조하는 테이블
db.User.belongsTo(db.Emd, {
foreignKey: "loc_code",
targetKey: "code",
});
// 모델이 참조되는 테이블
db.User.hasMany(db.Weather_in, {
foreignKey: "host",
sourveKey: "email",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
export default User;
import { DataTypes, Model } from "sequelize";
import User from "./user";
export class Weather_In extends Model {
static init(sequelize) {
return super.init(
{
host: {
type: DataTypes.STRING(320),
primaryKey: true,
references: {
model: User,
key: "email",
},
},
collected_at: {
type: DataTypes.DATE,
primaryKey: true,
},
temp: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
humi: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
lights: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
},
{
sequelize,
timestamps: false,
paranoid: false,
}
);
}
static associate(db) {
// 모델이 참조하는 테이블
db.Weather_in.belongsTo(db.User, {
foreignKey: "host",
targetKey: "email",
});
}
}
export default Weather_In;
import { DataTypes, Model } from "sequelize";
import Emd from "./emd";
export class Weather_Out extends Model {
static init(sequelize) {
return super.init(
{
loc_code: {
type: DataTypes.INTEGER,
primaryKey: true,
references: {
model: Emd,
key: "code",
},
},
collected_at: {
type: DataTypes.DATE,
primaryKey: true,
},
temp: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
humi: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
press: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
wind_speed: {
type: DataTypes.FLOAT,
defaultValue: 0,
},
},
{
sequelize,
timestamps: false,
paranoid: false,
}
);
}
static associate(db) {
// 모델이 참조하는 테이블
db.Weather_out.belongsTo(db.Emd, {
foreignKey: "loc_code",
targetKey: "code",
});
}
}
export default Weather_Out;
import fs from "fs";
import mysql from "mysql";
import dotenv from "dotenv";
dotenv.config();
// DB Connection
const db = mysql.createConnection({
host: process.env.MYSQL_HOST || "localhost",
user: process.env.MYSQL_USER || "root",
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE || "EUE",
});
const inputDo = (code, name) => {
name = name.replace(/\s/g, "");
let q = `INSERT INTO LOCDO (CODE,DONAME) VALUES (${code},'${name}');`;
db.query(q, (err, result) => {
if (err) {
console.log(err);
return;
}
console.log("Result : " + result);
});
};
const inputSi = (code, name, doCode) => {
name = name.replace(/\s/g, "");
let q = `INSERT INTO LOCSIGUNGU (CODE,DOCODE,SGGNAME) VALUES (${code},${doCode},'${name}');`;
db.query(q, (err, result) => {
if (err) {
console.log(err);
return;
}
console.log("Result : " + result);
});
};
const inputDong = (code, name, doCode, siCode) => {
name = name.replace(/\s/g, "");
let q = `INSERT INTO LOCINFO (CODE,DOCODE,SGGCODE,EMDNAME) VALUES (${code},${doCode},${siCode},'${name}');`;
db.query(q, (err, result) => {
if (err) {
console.log(err);
return;
}
console.log("Result : " + result);
});
};
const setDB = () => {
// DB Connect
db.connect((err) => {
if (err) {
console.log(err);
return;
}
console.log("connected as id" + db.threadId);
});
// File Read
let originData = fs.readFileSync("data/admAddressCode.csv", "utf8");
// Separate Data & Input Data
let sepData = originData.split("\r\n");
let setDoCode = new Set();
let setSiCode = new Set();
sepData.forEach((line) => {
line = line.replace(/\s/g, "");
let addr = line.split(",");
const doCode = Number(addr[0]);
if (!setDoCode.has(doCode)) {
const doName = addr[1];
inputDo(doCode, doName);
setDoCode.add(doCode);
}
const siCode = Number(addr[2]);
if (!setSiCode.has(siCode)) {
const siName = addr[3];
inputSi(siCode, siName, doCode);
setSiCode.add(siCode);
}
const dongCode = Number(addr[4]);
const dongName = addr[5];
inputDong(dongCode, dongName, doCode, siCode);
});
// Connection Close
db.end();
};
setDB();
/*
# EUE Server Database Schema
1. LOCDO
- 행정구역 도/특별시/특별자치시 이름과 코드 저장
- LOCSIGUNGU와 LOCINFO에 참조됨
2. LOCSIGUNGU
- 행정구역 시/군/구 이름과 코드 저장
- LOCDO를 참조
- LOCINFO에 참조됨
3. LOCINFO
- 행정구역 읍/면/동 이름과 코드 및 날씨 정보 URL 저장
- LOCDO와 LOCSIGUNGU를 참조
4. USER
- 사용자 ID, PassWord, 거주지역코드, 데이터 URL 저장
- LOCINFO를 참조
*/
CREATE TABLE LOCDO
(
CODE INT NOT NULL,
DONAME VARCHAR(20) NOT NULL,
PRIMARY KEY(CODE)
);
CREATE TABLE LOCSIGUNGU
(
CODE INT NOT NULL,
DOCODE INT NOT NULL,
SGGNAME VARCHAR(20) NOT NULL,
PRIMARY KEY(CODE),
FOREIGN KEY(DOCODE) REFERENCES LOCDO(CODE) ON UPDATE CASCADE ON DELETE RESTRICT
);
CREATE TABLE LOCINFO
(
CODE INT NOT NULL,
DOCODE INT NOT NULL,
SGGCODE INT NOT NULL,
EMDNAME VARCHAR(20) NOT NULL,
DATALINK TEXT,
PRIMARY KEY(CODE),
FOREIGN KEY(DOCODE) REFERENCES LOCDO(CODE) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY(SGGCODE) REFERENCES LOCSIGUNGU(CODE) ON UPDATE CASCADE ON DELETE RESTRICT
);
CREATE TABLE USER
(
ID VARCHAR(20) UNIQUE NOT NULL,
PW VARCHAR(20) NOT NULL,
LOCCODE INT NOT NULL,
DATALINK TEXT,
PRIMARY KEY(ID),
FOREIGN KEY(LOCCODE) REFERENCES LOCINFO(CODE) ON UPDATE CASCADE ON DELETE RESTRICT
);
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment