2020-04-17

【InfluxDB】型が合わなくてデータがインサート出来ない時【node-influx】

integerで登録されているfieldに正しく整数を送信するとfloatではダメだというエラーが出ることがある。対処法を記す。

Article Image

エラーの詳細

次のようなエラーを対処する。

message: 'A 400 Bad Request error occurred: {"error":"partial write: field type conflict: input field "data" on measurement "test" is type float, already exists as type integer dropped=1"}\n'

integerとして登録されているデータが floatで送られてきたため400のコードが帰っている。

このメッセージに騙されて汎ゆる手法でdataintegerに変換しようとしてしまうが、そもそJavaScriptには明示的にintegerfloatを分けるコードはない(numberという型になる)

確認

次のInfluxQLを実行してFieldsの型を確認する。

今回は"test_db"というDB名である。

SHOW FIELD KEYS ON "test_db"

結果

Chronografで表示

2020 04 17 21h01 37

画像の通り datainteger である。

コード(node-influx)

次のコードでデータ登録を試みる。

import Influx from 'influx'

const influx = new Influx.InfluxDB({
    host: 'localhost',
    database: 'test_db',
})

influx.writePoints([
    {
        measurement: 'test',
        fields: {
            data: 9999,
        },
        tags: []
    }
]).then((data) => {
    console.log(data)
}).catch((err) => {
    console.log(err)
})

JS的には何も問題ない。

node-influxとしても正しいコードだ。

9999は整数であるためintegerという認識で問題ない。

解決方法

実はこのエラーintegerfloatは関係なく冒頭でInfluxDBをnewしているコードに不備があるため発生する。

正しくは次のように宣言しなければならない。

const influx = new Influx.InfluxDB({
    host: 'localhost',
    database: 'test_db',
    schema: [
        {
            measurement: 'test',
            fields: {
                data: Influx.FieldType.INTEGER,
            },
            tags: []
        }
    ]
})

つまりJavaScriptとしてintegerを定義するのではなくInfluxDBのインスタンスを生成するときにschema(スキーマ)を明示するのである。

これならば正しく登録される。

余談

このエラーはDBに既にfieldsintegerで登録してある場合にのみ発生する。初めからスキーマを設定せずにdata:9999を登録すると自動でfloatで登録されるようで型指定エラーには出会わなくなる。

海外のフォーラムではintegerはもともと使わないほうが良いという声もあったが小数点以下を使用しないならintegerで絞りたいのはエンジニア的思考である。

デフォルトより明示的に指定したほうが良いと私は考えている。

所感

DBにデータを登録するコードが何箇所も別れている設計であるとこのエラーに出会いやすい。極力データを登録するコードはクラス化する等して絞った方が良いだろう。

誰かの参考になれば幸いだ。



この記事のタグ

この記事をシェア


謎の技術研究部 (謎技研)