MySQLからPostgreSQLへの移行が上手くいきません。

前提

お世話になります。

Node.jsで書かれたメモアプリで、以前はMySQLを接続していたのですが、この度PostgreSQLに移行することになりました。
それに伴い、お尋ねしたい問題がふたつございます。

ひとつめ・PostgreSQLと既存のコードが噛み合わない

移行にあたり必要なコードの書き換えなどは一通り終えたつもりなのですが、実行してみたところ、EJSファイルに次のようなエラーが発生しました(EJSというのは、HTML内にJavascriptを簡単に記述できるJSのテンプレートエンジンです)。

イメージ説明

まだPosrgreSQLに不慣れなため、おそらく書き換えの際に書式の間違いや誤字が発生したのだと思いますが、自力ではこれ以上見つけることができず……。
どうか皆様のお知恵をお貸しくださいませ。

ふたつめ・PostgreSQLの生成列でTo_charを使いたい

従来のMySQLでは、以下のように定義したカラムが存在します。

カラム名 VARCHAR(15) DEFAULT GENERATED ALWAYS AS (DATE_FORMAT(参照カラム名, '%b %d %y %k:%i')) STORED;

PostgreSQLでもこれと同様に機能するカラムを作りたいのですが、自分なりに調べて以下のように定義してみてもうまくいきませんでした。

カラム名 VARCHAR(15) DEFAULT GENERATED ALWAYS AS IDENTITY (To-char(参照カラム名, 'Mon DD YY HH24:MI'));

To-charの生成列での使い方を検索してみたのですが、SELECT文での使用例しか見つけることができずに行き詰まっております。
こちらについても、よい解決法をご教示いただけますと幸いです。

該当のソースコード・テーブル

次の1枚目の画像が新しく作ったPostgreSQLのmemosテーブルの構造、2枚目が以前から存在したMySQLのmemosテーブルの構造です。

イメージ説明

イメージ説明

また、該当のJSファイルとEJSファイルはこちらです。

app.js

1const express = require('express'); 2const mod = require('./module') 3const app = express(); 4 5app.use(express.static('public')); 6app.use(express.urlencoded({extended: false})); 7 8// ルートURLへのアクセスがあった際に/indexにリダイレクトする 9app.get('/', (req, res) => { 10 res.redirect('/index'); 11}); 12 13// Memo Listの取得 14app.get('/index', (req, res) => { 15 const connection = mod.connection; 16 connection.query( 17 'SELECT * FROM memos WHERE is_removed = false', 18 (err, data) => { 19 console.log(data); 20 res.render('index.ejs', {memos: data}); 21 connection.end(); 22 } 23 ); 24}); 25 26// 新規メモの作成ページを表示 27app.get('/new', (req, res) => { 28 res.render('new.ejs'); 29}); 30 31// 新規メモを保存 32app.post('/create', (req, res) => { 33 const connection = mod.connection; 34 connection.query( 35 'INSERT INTO memos (title, content) VALUES (?, ?)', 36 [req.body.memoTitle, req.body.memoContent], 37 (err, data) => { 38 res.redirect('/index'); 39 connection.end(); 40 } 41 ); 42}); 43 44// メモの編集ページを取得 45app.get('/edit/:id', (req, res) => { 46 const connection = mod.connection; 47 connection.query( 48 'SELECT * FROM memos WHERE id = ?', 49 [req.params.id], 50 (err, data) => { 51 res.render('edit.ejs', {memo: data[0]}); 52 connection.end(); 53 } 54 ); 55}); 56 57// メモを更新 58app.post('/update/:id', (req, res) => { 59 const connection = mod.connection; 60 connection.query( 61 'UPDATE memos SET title = ?, content= ? WHERE id = ?', 62 [req.body.memoTitle, req.body.memoContent, req.params.id], 63 (err, data) => { 64 res.redirect('/index'); 65 connection.end(); 66 } 67 ); 68}); 69 70// Trash Listの取得 71app.get('/trash', (req, res) => { 72 const connection = mod.connection; 73 connection.query( 74 'SELECT * FROM memos WHERE is_removed = true', 75 (err, data) => { 76 console.log(data); 77 res.render('trash.ejs', {memos: data}); 78 connection.end(); 79 } 80 ); 81}); 82 83// メモを/indexから/trashへ 84app.post('/remove/:id', (req, res) => { 85 const connection = mod.connection; 86 const id = req.params.id; 87 connection.query( 88 'UPDATE memos SET is_removed = true WHERE id = ?', 89 [id], 90 (err, data) => { 91 res.redirect('/index'); 92 connection.end(); 93 } 94 ); 95}); 96 97// メモを/trashから/indexへ 98app.post('/restore/:id', (req, res) => { 99 const connection = mod.connection; 100 const id = req.params.id; 101 connection.query( 102 'UPDATE memos SET is_removed = false WHERE id = ?', 103 [id], 104 (err, data) => { 105 res.redirect('/trash'); 106 connection.end(); 107 } 108 ); 109}); 110 111// /trashからメモを完全削除 112app.post('/delete/:id', (req, res) => { 113 const connection = mod.connection; 114 const id = req.params.id; 115 connection.query( 116 'DELETE FROM memos WHERE id = ?', 117 [id], 118 (err, data) => { 119 res.redirect('/trash'); 120 connection.end(); 121 } 122 ); 123}); 124 125// Trash Listを空にする 126app.post('/empty', (req, res) => { 127 const connection = mod.connection; 128 connection.query( 129 'DELETE FROM memos WHERE is_removed = true', 130 (err, data) => { 131 res.redirect('/trash'); 132 connection.end(); 133 } 134 ); 135}); 136 137const port = process.env.PORT || 8001; 138 139app.listen(port, () => { 140 console.info(`Listeninng on ${port}`); 141}); 142/* 143const connection = mod.connection; 144connection.connect((err) => { 145 if (err) { 146 console.log('error connecting: ' + err.stack); 147 return; 148 } 149}); 150*/ 151

index.ejs

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Kanon's Memo</title> 8 <link rel="icon" href="/images/black-cat.png"> 9 <link rel="stylesheet" href="/css/style.css"> 10</head> 11<body> 12 <%- include('header'); %> 13 <main> 14 <div class="index-container"> 15 <div class="container-header"> 16 <div class="container-title"> 17 <h1>Memo List</h1> 18 <img src="/images/black-cat.png" alt="S-cat" class="cat-image"> 19 </div> 20 <div class="button"> 21 <a href="/trash"class="optional-button move-button">Trash</a> 22 <a href="/new" class="optional-button">+ New</a> 23 </div> 24 </div> 25 <div class="index-table-wrapper"> 26 <div class="table-head"> 27 <span class="title-column">Name</span> 28 <span class="modified-column">Last Modified</span> 29 </div> 30 <ul class="table-body"> 31 <% memos.forEach((memo) => { %> 32 <li> 33 <span class="title-column"><%= memo.title %></span> 34 <div class="items"> 35 <span class="modified-column"><%= memo.modified %></span> 36 <div class="icon-area"> 37 <div class="menu-icon"> 38 <div></div> 39 <div></div> 40 <div></div> 41 </div> 42 <ul class="menu-content"> 43 <li><a href="/edit/<%= memo.id %>">Edit</a></li> 44 <li><form action="/remove/<%= memo.id %>" method="post"> 45 <input type="submit" value="Remove"> 46 </form></li> 47 </ul> 48 </div> 49 </div> 50 </li> 51 <% }); %> 52 </ul> 53 </div> 54 </div> 55 <div class="footer"> 56 <small class="copy-right">&copy; 2023 kanon</small> 57 </div> 58 </main> 59</body> 60</html>

他にご入用の情報があれば仰っていただければ追記いたします。

補足情報(FW/ツールのバージョンなど)

実行環境はWindows11です。

Node: v16.14.2
MySQL: v8.0.3
PostgreSQL: v16.1

どうぞよろしくお願いいたします。

コメントを投稿

0 コメント