http://q.hatena.ne.jp/1441975146


上記の続きです。
データベースの中のみでの重複チェックは調べてわかったのですが、登録したいデータがデータベースに重複していないか、そこで重複していないデータを登録する、という手順まではわかりませんでしたので、質問したいと思います。
外部データをデータベースに登録する際に、、どうしようかというのがわかりませんでした。

できれば、このRuby構文をこのままどうすればいいか教えて頂ければ助かります。
Sqlite3への登録部分ではありますが、小さな思い込みから行き止まりになることが多々あったので、、
よろしくお願いします。。

回答の条件
  • 1人10回まで
  • 13歳以上
  • 登録:2015/09/30 16:59:01
  • 終了:2015/10/06 16:15:29

ベストアンサー

id:a-kuma3 No.1

a-kuma3回答回数4490ベストアンサー獲得回数18582015/09/30 17:48:15

ポイント1500pt

SQLite には INSERT OR REPLACE というのがあります。
これを使うと、プライマリキーが重複するレコードがあると上書きしてくれます。

def treat_data data

    ...

    // ★         ↓ ここ!
    sql = 'insert or replace into TEPCO(blackout_time, recover_time, pref, city, area, blackout_count, blackout_reason, update_time) values (?, ?, ?, ?, ?, ?, ?, ?);'
    db.execute(sql, [blackout_time, recover_time, pref, city, area, blackout_count, blackout_reason, update_time])

    ...

前回は手抜きして、通し番号の id なんてカラムを作ってプライマリキーにしましたが、もう必要ないですね。
id カラムを削除して、適当なキーをプライマリキーに指定してください。
例えば、発生時刻、都県、市町村あたりがプライマリキーでしょうか。

CREATE TABLE TEPCO (
    blackout_time   text,
    recover_time    text,
    pref    text,
    city    text,
    area    text,
    blackout_count  text,
    blackout_reason text,
    update_time text,
    PRIMARY KEY(blackout_time,pref,city)
);


停電情報が変わっていく様子も追っかけたい、というようなこともおっしゃってたので、用途に合わせてプライマリキーを決めてください。





追記です。

普通のというか、データがあるかどうかを判定して insert と update を切り替えて使うというベタな方法も書いておきます。

def treat_data data

    ...

    # プライマリキーで数を確認
    sql = 'select count(*) from TEPCO where blackout_time = ? and pref = ? and city = ?'
    rs = db.execute(sql, [blackout_time, pref, city])

    # データが無かったら insert
    if rs[0][0] == 0 then
        sql = 'insert into TEPCO(blackout_time, recover_time, pref, city, area, blackout_count, blackout_reason, update_time) values (?, ?, ?, ?, ?, ?, ?, ?);'
        db.execute(sql, [blackout_time, recover_time, pref, city, area, blackout_count, blackout_reason, update_time])
    # データがあったら update
    else
        sql = 'update TEPCO set blackout_time = ?, recover_time = ?, pref = ?, city = ?, area = ?, blackout_count = ?, blackout_reason = ?, update_time = ? where blackout_time = ? and pref = ? and city = ?'
        db.execute(sql, [blackout_time, recover_time, pref, city, area, blackout_count, blackout_reason, update_time, blackout_time, pref, city])
    end

ひとつのデータを書き込むのにふたつの SQL を出してたりするような性能面のこともありますが、ぱっと見てわかるように何よりも見づらい。
見づらさはメンテナンス性を悪くします。
多分、ちょいちょいいじるプログラムになるんだと思います。
保存する DB のレイアウトを変えたりしたくなることもあるかもしれない。
そういった辺りを考えると、シンプルなソースにしておくのが良いと思います。

他3件のコメントを見る
id:FREEz

対象URLを追加していったら、一気に複数追加すると飛ばして対応してしまうことがありました。
ID残しておいてよかったです。一目瞭然に気付いたので。
URLをひとつずつ追加すると、問題なく追加されました、、ふたつ追加すると飛ばすこともありましたw
一度登録できないと飛ばしたところは再度動かしても追加されず、、注意しないといけないなぁ、、と。
あとは原因変わったら更新されるか、試したいけど変わらないと試せないから。。

2015/10/07 16:51:47
id:FREEz

しばらく使ってみて気付いたのですが、
1日の結果として『停電履歴情報はありません。』の際に処理を飛ばすif文を入れた方がいいですね。
今のままだと 停電履歴情報はありません。 と書き込まれてしまうので、、
複数のURLで連続で処理しているとちゃんとなっているか不安でひとつずつチェックしていますが、原因が判明して書き換えられることがいまのところないので、判断できず、、

2015/10/16 03:15:35

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません