node.jsでsqlite3を利用する機会があったのでメモ。
前提
- 私の環境はMac(なので最初からsqlite3が入っている)sqlite3 --versionで確認可能。
- node.jsがインストールされている
準備
作業場所やファイルの生成
作業場所を作る。名前は何でも良い。ここではindex.jsに実装していく。
mkdir node-sqlite3-test
cd node-sqlite3-test
npm init -y
touch index.js
sqlite3をnode.jsから制御するためのモジュールをインストール
sqlite3と同名なのでややこしいといえばややこしい。
npm install sqlite3
これはsqlite3をインストールしてるのではなく、制御モジュールのインストール。
基本(だが、悪い例)
早速実装。
実装例
モジュール読み込んで、newして、db.run()でいろいろ実行するのが基本。
ただ、感の良い人は気づくと思いますが、db.run()は非同期で実行されます。
const sqlite3 = require("sqlite3");
const db = new sqlite3.Database("./test.db");
// db.run("drop table if exists members");
db.run("create table if not exists members(name,age)");
db.run("insert into members(name,age) values(?,?)", "hoge", 33);
db.run("insert into members(name,age) values(?,?)", "foo", 44);
db.each("select * from members", (err, row) => {
console.log(`${row.name} ${row.age}`);
});
db.close();
実行例
とりあえず実行してみます。
node index.js
いちおう期待通りの動き。
hoge 33
foo 44
実行例2
次に、// db.run("drop table if exists members"); をコメントインして実行してみます。
するとエラーが発生します。
エラーは下記と異なる場合もあり、かつ、実行のたびに違うエラー(あるいは正常終了)になることもあります。
[Error: SQLITE_ERROR: no such table: members
Emitted 'error' event on Statement instance at:
] {
errno: 1,
code: 'SQLITE_ERROR'
}
上記エラーは、insert時にmembersというテーブルが無いよ!というエラーです。
つまり、テーブルは生成される前にinsertが実行されているということです。
順番(同期的)に実行する
矛盾なく順番に実行するにはdb.serializa()で処理を囲ってやるようです。
実装1
下記の通り。
const sqlite3 = require("sqlite3");
const db = new sqlite3.Database("./test.db");
db.serialize(() => {
db.run("drop table if exists members");
db.run("create table if not exists members(name,age)");
db.run("insert into members(name,age) values(?,?)", "hoge", 33);
db.run("insert into members(name,age) values(?,?)", "foo", 44);
db.run("update members set age = ? where name = ?", 55, "foo");
db.each("select * from members", (err, row) => {
console.log(`${row.name} ${row.age}`);
});
db.all("select * from members", (err, rows) => {
console.log(JSON.stringify(rows));
});
db.get("select count(*) from members", (err, count) => {
console.log(count["count(*)"]);
})
});
db.close();
こっそりupdateや全レコード取得,count処理を加えてます。
実行
実行すると期待通りの結果が得られるようです。
node index.js
hoge 33
foo 55
実装2
下記のようにチェーンメソッド的に書くこともできる(省略)。
db.run("create table if note exists members(name,age)",[],(err)=>{
db.run("insert into members(name,age) values("hoge",11)");
});
メモ
- db.parallelize()関数もあり、明示的に並行処理させることもできます。
- sqlite3自体を直接操作する方法はこちらをご覧ください