LoginSignup
4
6

More than 3 years have passed since last update.

InfluxDB-Pythonでナノ秒単位のデータを登録する

Last updated at Posted at 2019-10-04

はじめに

InfluxDBのpythonクライアント(InfluxDB-Python)でナノ秒単位のデータを登録する際に、タイムスタンプが崩れるため工夫が必要だったという話です。

環境

  • OS: Windows 10
  • InfluxDB: v1.7.8
  • Python: v3.7.4
  • InfluxDB-Python: v5.2.3

再現コード

InfluxDB-PythonのREADMEを参考にして、ナノ秒単位のデータ登録を行ってみます。

from influxdb import InfluxDBClient

if __name__ == '__main__':
    client = InfluxDBClient('localhost', 8086)
    ts = '2019-01-01T00:00:00.123456789Z'
    body = [{
        'measurement': 'cpu',
        'time': ts,
        'fields': {
            'sys': 12.3,
            'usr': 45.6,
        }
    }]
    client.write_points(body, database='my_db', time_precision='n')

サーバ設定はデフォルトのままです。期待ではそのままのタイムスタンプで登録されていて欲しかったのですが、サーバには丸められたタイムスタンプで登録されていました。

> select * from cpu
name: cpu
time                sys  usr
----                ---  ---
1546300800123456000 12.3 45.6

他にも例えば「2019-01-01T00:00:00.123Z」のようにミリ秒単位のタイムスタンプを指定すると、「1546300800122999808」とズレたタイムスタンプで入ってしまうのが困りました。

対応コード

どうもクライアント側で丸められているようでした。タイムスタンプをUnix時刻(ナノ秒)で指定すると問題なさそう。

from influxdb import InfluxDBClient

if __name__ == '__main__':
    client = InfluxDBClient('localhost', 8086)
    ut = 1546300800123456789
    body = [{
        'measurement': 'cpu',
        'time': ut,
        'fields': {
            'sys': 12.3,
            'usr': 45.6,
        }
    }]
    client.write_points(body, database='my_db', time_precision='n')

これだとうまく入ります。

> select * from cpu
name: cpu
time                sys  usr
----                ---  ---
1546300800123456789 12.3 45.6

InfluxDB-Pythonのナノ秒単位のタイムスタンプの文字列の扱いにはどうも制約があるようです。ナノ秒単位のデータを扱い得るときには、基本的に整数型で指定する方がよいように思います。

ちなみにタイムスタンプの文字列(RFC3339)をナノ秒単位のUnix時刻に変換するには、標準ライブラリでさくっと、というわけにはいかなさそうです。いちばん手軽にできるのはnumpyのdatetime64ですかね。

from influxdb import InfluxDBClient
import numpy

if __name__ == '__main__':
    client = InfluxDBClient('localhost', 8086)
    ts = '2019-01-01T00:00:00.123456789Z'
    dt = numpy.datetime64(ts, 'ns')
    ut = dt.astype('uint64')
    body = [{
        'measurement': 'cpu',
        'time': ut,
        'fields': {
            'sys': 12.3,
            'usr': 45.6,
        }
    }]
    client.write_points(body, database='my_db', time_precision='n')

おわりに

InfluxDB-Pythonでナノ秒単位のデータを登録する際に、タイムスタンプの文字列の扱いに制約があるため工夫が必要だったという話でした。

参考

4
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
4
6