React + Node + Docker + Postgres (#4 Postgres構築)
DockerでPostgreSQLを起動させ、NodeからSequelizeを利用しアクセスできるようにします。(前回の記事は下記になります)
PostgreSQL構築
Dockerfileを作成します。
mkdir -p ./db/init
touch ./db/Dockerfile.db
Dockerfile.db
FROM postgres:12-alpine
EXPOSE 5432
COPY ./db/init /docker-entrypoint-initdb.d
DB起動時にテーブルを作成するためのファイルを作成します。
touch ./db/init/1_createtable.sql
touch ./db/init/2_insert-task.sql
1_createtable.sql
create table if not exists task(
id SERIAL PRIMARY KEY,
title VARCHAR(20),
description VARCHAR(100),
"createdAt" TIMESTAMP NOT NULL,
"updatedAt" TIMESTAMP NOT NULL
);
2_insert-task.sql
INSERT INTO task (title, description, "createdAt", "updatedAt") VALUES ('postgres構築', 'Sequelizeからアクセスする', now(), now());
docker-compose.ymlのservicesにpostgresを追加します。
docker-compose.yml
postgres:
build:
context: .
dockerfile: ./db/Dockerfile.db
ports:
- 5432:5432
environment:
POSTGRES_USER: postgres
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
networks:
- react-node-docker-postgres
PostgreSQLだけ起動してみます。
docker-compose up --build postgres
PostgreSQLにアクセスしてみます。
taskテーブルが作成されて、データも登録されています。
私は「TablePlus」というDBクライアントを利用しています。
SequelizeでPostgreSQLにアクセス
Sequelizeをインストールします。
npm i -D sequelize-cli sequelize pg
PostgreSQLにアクセスするための設定ファイル、JSファイルを作成します。
cd src/app/js
npx sequelize init
npx sequelize model:generate --name task --attributes title:string,description:string
上記のコマンドを実行すると、下記のディレクトリ、ファイルが作成されます。
├── config
│ └── config.json
├── migrations
│ └── 20201015193015-create-task.js
├── models
│ ├── index.js
│ └── task.js
└── seeders
DBの設定を編集します。
./src/app/js/config/config.json
{
"development": {
"username": "postgres",
"password": "postgres",
"database": "postgres",
"host": "postgres",
"dialect": "postgres"
}
}
このコマンドで作成されるモデルはテーブル名を複数形で扱うので、下記を追加します。
「freezeTableName: true」
./src/app/js/models/task.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class task extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
};
task.init({
title: DataTypes.STRING,
description: DataTypes.STRING
}, {
sequelize,
modelName: 'task',
freezeTableName: true
});
return task;
};
DBにアクセスしてレコードを取得するAPIを追加します。
./src/app/js/main.js
const express = require("express");
const path = require("path");
const db = require('./models/index')
const app = express();
app.get('/api/node', (req, res) => {
res.send({api: 'Connected Node!'});
})
app.get('/api/docker', (req, res) => {
const dockerMsg = 'Connected Docker!';
res.send({docker: dockerMsg});
})
app.get('/api/postgres', (req, res) => {
db.task.findAll().then(tasks => {
res.send(tasks);
});
})
app.listen(3000, ()=> {
console.log('app running');
})
フロントエンドに追加したAPIを呼び出し、画面に表示できるようにします。
cd ../../../
mkdir ./src/front/js/task
touch ./src/front/js/task/Task.jsx
Task.jsx
import React, { Component } from 'react';
import { getJSON } from "../utils/HttpUtils";
export default class TaskApp extends React.Component {
state = {
taskResult: []
}
componentDidMount() {
const taskResponseJson = getJSON("/api/postgres")
.then(taskResponseJson => this.setState({ taskResult: taskResponseJson }));
}
render() {
const taskRows = this.state.taskResult.map((task,index) =>
<tr key={task.id}>
<td>{task.title}</td>
<td>{task.description}</td>
</tr>
);
return (
<div className="TaskApp">
<table border='1' cellSpacing='0'>
<thead>
<tr>
<th>タイトル</th>
<th>詳細</th>
</tr>
</thead>
<tbody>
{taskRows}
</tbody>
</table>
</div>
);
}
}
./src/front/js/main.js
import React from "react";
import ReactDOM from "react-dom";
import NodeApp from './node/Node'
import TaskApp from './task/Task'
const Index = () => {
return (
<div>Hello React! <NodeApp /> <TaskApp /></div>
);
};
ReactDOM.render(<Index />, document.getElementById("root"));
起動すると下記のように表示されます。
ここまでのものはこちらになります。
https://github.com/YosukeKondo/react-node-docker-postgres/releases/tag/v4.0_postgres
この記事が気に入ったらサポートをしてみませんか?