6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SQLite3の旧データベースをMongoDBへ引っ越し

Last updated at Posted at 2012-09-09

昨日の休日練習で試した node-csv-parser ( http://qiita.com/items/b8137a66ca35e1b6a729 ) がうまくいったのに気をよくして(^^)v、、、

今日は業務で使ってたSQLite3の旧データベースをMongoDBへさくっと引っ越してみました。

SQLite3のデータをダンプ

まず、旧データベース側のデータを全部出力してみます。

$ sqlite3 hoge.db 
sqlite> .output 20120909.dump
sqlite> .dump

これで20120909.dumpというテキストデータが出来上がります。こんなの。

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE hoge (
    ctime     INTEGER NOT NULL,
    date      TEXT NOT NULL,
    eventName TEXT,
    type      TEXT,
    status    TEXT,
    clientId  TEXT
  );
INSERT INTO "hoge" VALUES(1343096611063,'da.2012.7.22','event127878','hoge','tyu','157183_1343096648191');
INSERT INTO "hoge" VALUES(1343096624381,'da.2012.7.22','event129600','hoge','tyu','157183_1343096648191');
INSERT INTO "hoge" VALUES(1343096625820,'da.2012.7.22','event129600','hoge','zumi','157183_1343096648191');
  (略)
INSERT INTO "hoge" VALUES(1347159497371,'da.2012.9.9','event138761','hoge','tyu','375533_1347147506930');
CREATE INDEX date ON hoge (date COLLATE NOCASE);
COMMIT;

要するにSQL文がずらずら書かれているやつ。

これを実行すればCREATE TABLE文でテーブルが再構築されて、そこへINSERT文でデータをズンズン入れていけば、リストアできちゃうというわかりやすいバックアップ。

で、同じタイプのDB、つまりSQLite3へ入れるならこれで復元すれば良いのだけれど、今回はこれをMongoDBへ放り込もうという物語。

データ量は数千件程度と少ないので考え考え手作業しながらやてまう。

サイボウズの日付スタイル'da.2012.7.22'とかイベントの書き方'event127878'を流用してることに気付いたあなたはサイボーザー?まぁ、サンプルデータなのでアバウトですけど、このサンプルなど( http://jsgt.org/sb/ws/test.htm )で使ってるやつでサイボウズを四苦ハックしての運用版です。

Mongoのスキーマを決める

スキーマレスなのにスキーマとは、、、という無駄な?ことは考えず、マングース様の言うとおりMongoのスキーマを考えておく。

こんな感じ。

// スキーマ
var hogeSchema = {
   ctime     : { type: Number, default: Date.now } //サーバーへの登録時
  ,date      : { type: String, required: true, index: true} //スケジュールの日付
  ,eventName : { type: String} //イベントID
  ,type      : { type: String, required: true } //メッセージのタイプ
  ,status    : { type: String } //メッセージステータス
  ,clientId  : { type: String } //クライアントID
};

新しいデータのサンプル

データサンプルで見るとこんな感じになります。SQLite3の各カラムをJavaScriptのオブジェクトにして放り込もうという作戦。

データサンプル  {
   ctime     : 1342322851988
  ,date      : "da.2012.7.15"
  ,eventName : "event125197"
  ,type      : "hoge"
  ,status    : "zumi"
  ,clientId  : "609369_1342319334920"
}

作戦会議

さて、上のSQLite3のデータをどうやってMongoへ放り込むと簡単でしょう?
はいっ。テキストデータをnode-csvで読み込んでマングースへ食わせる手がありますっ。
採用っ。

準備

上のデータのSQL文をそぎ落とし、ダブルクオートにしてCSVぽくしてみます。

20120909.txt
1343096611063,"da.2012.7.22","event127878","hoge","tyu","157183_1343096648191"
1343096624381,"da.2012.7.22","event129600","hoge","tyu","157183_1343096648191"
1343096625820,"da.2012.7.22","event129600","hoge","zumi","157183_1343096648191"
  (略)
1347159497371,"da.2012.9.9","event138761","hoge","tyu","375533_1347147506930"

とりあえず、これを20120909.txtとか名前を付けて保存します

さて、一気にやります。

csv2mongo.js
//CSV perser
var csv = require('csv');
//入力データ
var infile = __dirname+'/20120909.txt';

// マングース降臨
var mongoose = require('mongoose');
// スキーマ
var UketukeSchema = {
   ctime     : { type: Number, default: Date.now } //サーバーへの登録時
  ,date      : { type: String, required: true, index: true} //スケジュールの日付
  ,eventName : { type: String} //イベントID
  ,type      : { type: String, required: true } //メッセージのタイプ
  ,status    : { type: String } //メッセージステータス
  ,clientId  : { type: String } //クライアントID
};

// DB接続
var conn = mongoose.createConnection('mongodb://localhost/hoge');
// スキーマ定義
var schema = new mongoose.Schema(UketukeSchema);
// モデル定義
var model = conn.model('Uketuke', schema);

//全削除してから、、、
delAll (function(){})
//全インストール
csv2mongo(infile);

// 全データ削除
function delAll (callback) {
  var U = new model();
  model
    .find({})
    .remove()
  U.save(function(err) {
    if (err) { console.log(err); }
    else callback(U);
  });
}

// データ挿入
function insert (data, callback) {
  var ins = new model();

  //ins.ctime = data.ctime; //nowを入れるなら不要
  ins.date = data.date;
  ins.eventName = data.eventName;
  ins.type = data.type;
  ins.status = data.status;
  ins.clientId = data.clientId;

  ins.save(function(err) {
    if (err) { console.log('/////////////////////////'+err); }
    else callback(data, ins);
  });
}

//CSVをマングースへ食わせろっ
function csv2mongo(infile){
  
  csv()
    .fromPath(infile) //読み込むCSVファイル
    .transform(function(data){
        var data ={
             ctime     : data[0] //データの対応注意
            ,date      : data[1]
            ,eventName : data[2]
            ,type      : data[3]
            ,status    : data[4]
            ,clientId  : data[5]
        };
            
        //DBへ記録
        insert(data,
          function(data, ins){
            console.log('==inserted');
          }
        ); 
        console.log(data);
        return data;
    })
    .on('data',function(data){
        console.log(data);
    })
    .on('end',function(count){
        console.log('Number of lines: '+count);
    })
    .on('error',function(error){
        console.log(error.message);
    }) 
}

実行

node csv2mong.js

出来上がり。

ちなみに、実際にはうちではMongoのレプリカントさんなので、マングースは3匹こんな感じで接続してます。(参考: http://qiita.com/items/b5e99bf4923b84b2bb40 )

//レプリカリスト
var ReplicaSets = ''
  + 'mongodb://192.168.1.11:27020/hoge,'
  + 'mongodb://192.168.1.12:27020/hoge,'
  + 'mongodb://192.168.1.13:27020/hoge,'

// DB接続
var conn = mongoose.connectSet(ReplicaSets);

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?