素人が2020年までの1ヶ月でLINE BOTに挑戦する毎日note. 【Day 28:開発4日目_LINEログイン後にDBへデータを保存】
こんにちは。くろです。
12月1日から2019年残り1ヶ月でスケジュール調整BOTの開発に挑戦しています。今日は28日目です。
概要
開発アプリ:Googleカレンダーと連動してスケジュールを調整してくれるLINEBOT
BOTの概要:Day 2の記事に書いています。
BOTの仕様:機能一覧やフローチャート Day 10の記事に書いています。
BOTの開発環境:Day25の記事でアプリケーションの骨格を作りました。
昨日は「2,LINEログインしてマイページを表示する」のうちLINEログインの実装までを書きました。
今日はDBにユーザーデータを保存してDBへデータを保存する所まで書きます。
2-2,DBへユーザデータを保存
ちょっと前にherokuにpostgresqlというDBを接続しましたが、使い方がさっぱりなので、まずは学習からです。はやく開発したい、、、
調べているとどうやらSQL文というのを書ける必要があるみたいです。
heroku pg:psqlでherokuのpostgresqlにコマンドプロンプトからアクセスできる。その中でSQL文を叩くといろいろ実行できそうです。その後、\dって打てば、今あるTABLEの一覧が出てくるよう。
ただ、ここに打ってやっていくのか疑問はありますが、、、
SQLのコマンドはこの辺をざっと眺めておきました。
下記の2つの記事を組み合わせてデータベースを呼び出せるようにしました。
こんな感じにしてみました。
index.js
var { Client } = require('pg');
var connection = new Client({
user: 'hogehoge',
host: 'hogehoge',
database: 'hogehoge',
password: 'hogehoge',
port: 5432
});
connection.connect()
ここまででpgというモジュールを使ってpostgresqlへ接続しています。
本当は別ファイルに入れたかったのですが、試行錯誤した結果ちょっと難しかったので、index.jsにいれてます。
hogehoge部分はherokuのpostgresqlのsetting>Database Credentialsの中にかいているやつをコピペです。
あ、これでもあれか環境変数に入れて読み出さないといけないな。とおもったので、変えました。
var { Client } = require('pg');
var connection = new Client({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DB_PASSWORD,
port: process.env.DB_PORT
});
connection.connect()
それぞれの環境変数をherokuの環境変数にいれました。
これで好きな所でconnection.query()を呼び出して、()の中にsql文を書けばいけそうなきがします。
まずはres.send(body)の後に、データベースへデータをインサート挿入するコードを書きます。
const linelogin_uid_insert = {
text: 'INSERT INTO users (line_uid) VALUES($1)',
values: [JSON.parse(body).userId],
}
connection.query(linelogin_uid_insert)
.then(res => console.log("insert", res))
.catch(e => console.error(e.stack))
実行してみると、テーブルがないって言われたので、テーブルを作るコードをインサートの前に入れます。
index.js
connection.query(db.create_table)
.then(res => console.log(res.rows[0]))
.catch(e => console.error(e.stack))
ここはなんとかがんばってdb.jsという別のファイルからcreate_tableを読み出すようにできました。db.jsに配列を書いて、それをindex.jsの上部で読み出しておくと、db.create_tableで呼び出すことができました。
index.js
const db = require('./routes/db');
db.js
//SQLで使う関数を書いていく
var create_table = {
text: 'CREATE TABLE IF NOT EXISTS users (id SERIAL NOT NULL, line_uid VARCHAR(255) NOT NULL UNIQUE, google_id VARCHAR(255), display_name VARCHAR(255), created_at TIMESTAMP, updated_at TIMESTAMP, PRIMARY KEY (id))',
};
exports.create_table = create_table;
この時IF NOT EXISTSをいれないと、もうそのデータベースあるよって怒られます。これを入れると。usersっていうデータベースが存在している時は新しく作らないようになるので、回避できます。
また、idは行が増えるたびに勝手に1ずつ増やして番号をつけていって欲しいので、AutoIncrementというオプションをつけたのですが、これはmysqlでの仕様で、postgresqlでは使えないようでした。代わりに、オプションではなく、型をserial型にすると進めることができました。
AUTO_INCREMENTとは
カラムに値が指定されなかった場合、MySQLが自動的に値を割り当てる。
データ型は整数。
値は1ずつ増加して連番になる。
https://qiita.com/shonansurvivors/items/4522f15c5e9a30860bc5
最後にSELECTを入れてDBにデータが入っているか確認できるようにしました。res.row[0]で入れたデータが見れるっぽいんですが、ちょっとundefinedになってres.row[1]とかでも出なかったので、resだけコンソールで表示したらINSERTではこんな結果になってました。
command: 'INSERT'
rowCount: 1
oid: 0
rows: []
fields: undefined
_parsers: undefined
_types: TypeOverrides
_types: {
getTypeParser: [Function:
setTypeParser: [Function:
arrayParser: [Object]
builtins: [Object]
}
text: {}
binary: {}
}
RowCtor: null
rowAsArray: FALSE
}
rowsの[]に何も入ってないからそらこやんわな。
逆にSELECTの方はちゃんとコンソールログにでてきましたし、コマンドプロンプトからheroku pg:psqlを叩いた後に、select * from users;を叩くと、しっかりDBに入ってました。3行あるのは3回試してしまったからです。
はいここで、お気づきの方もおられるかもしれませんが、同じuidやのに2個もidが作られると困りますよね、、、
そこを修正していきます。
が、ちょっと色々調べて、
// text: 'INSERT INTO users (line_uid) SELECT $1 AS VARCHAR WHERE NOT EXISTS (SELECT id FROM users WHERE line_uid = $1)',
こういうやつとかを試したんですが、ちょっと前に進まなくなったので、一旦usersテーブルを作る時にline_uidをUNIQUE設定にすることで、登録しようとするとエラーになるようにしておきました。本当は良くない気がするが、、
var create_table = {
text: 'CREATE TABLE IF NOT EXISTS users (id SERIAL NOT NULL, line_uid VARCHAR(255) NOT NULL UNIQUE, google_id VARCHAR(255), created_at TIMESTAMP, updated_at TIMESTAMP, PRIMARY KEY (id))',
};
exports.create_table = create_table;
下記も進めたかったのですが、もろもろの修正ですごく時間を取られてしまったので、ちょっと明日に回させてもらいます。。。
やっぱり基礎をざっと学びたいな、、、
明日は
2-3,マイページ作成
2-4,DBからデータを取得してマイページに表示
をかきます。
・メモ
・pgのリファレンス
他のjsファイルのモジュールを呼び出す方法
データ型
この記事が参加している募集
よろしければサポートお願いします! 頂いたサポートはクリエイター活動に活用させて頂きます。