DuckDBにJSONを食わせてみる

 DuckDBにCSVを食わせてみたけど、こんどはJSONを食わせてみたい。AWS IoTとかで送られてくるのはLambdaとかで処理されていなければ、普通はJSONだから。

 とりあえず、AWS IoTで吐きそうなダミーデータをPythonで吐いてみる。デバイスIDとタイムスタンプ、温度と湿度と機器のステイタス、バッテリ状態くらいかな。送信デバイスは10個。タイムスタンプは1分に一回の時系列送信で、12月1日から10日まで。

import json

import random

from datetime import datetime, timedelta

固定デバイスIDリスト

device_ids = [

"device_001",

"device_002",

"device_003",

"device_004",

"device_005",

"device_006",

"device_007",

"device_008",

"device_009",

"device_010",

]

JSONデータのサンプルフォーマットを生成する関数

def generate_iot_data(device_id, timestamp):

status = random.choice(["active", "inactive", "error"])

if status in ["inactive", "error"]:

temperature = 0.0

humidity = 0.0

battery = 0.0

else:

temperature = round(random.uniform(15.0, 35.0), 2)

humidity = round(random.uniform(30.0, 70.0), 2)

battery = round(random.uniform(20.0, 100.0), 1)

return {

"device_id": device_id,

"timestamp": timestamp.isoformat(),

"temperature": temperature,

"humidity": humidity,

"status": status,

"battery": battery

}

12月1日から10日まで1分間隔のデータ生成

start_date = datetime(2024, 12, 1, 0, 0)

end_date = datetime(2024, 12, 10, 23, 59)

interval = timedelta(minutes=1)

data_list = []

current_time = start_date

while current_time <= end_date:

for device_id in device_ids:

data_list.append(generate_iot_data(device_id, current_time))

current_time += interval

ファイルに書き出し

data_file = "iot_sample_data.json"

with open(data_file, "w", encoding="utf-8") as file:

json.dump(data_list, file, ensure_ascii=False, indent=4)

print(f"{len(data_list)}個のIoTデータを{data_file}に出力しました。")

 実行すると、28.5MBのJSONファイルが生成された。

 中身はこんな感じ。

[

{

"device_id": "device_001",

"timestamp": "2024-12-01T00:00:00",

"temperature": 0.0,

"humidity": 0.0,

"status": "error",

"battery": 0.0

},

{

"device_id": "device_002",

"timestamp": "2024-12-01T00:00:00",

"temperature": 0.0,

"humidity": 0.0,

"status": "error",

"battery": 0.0

},

{

"device_id": "device_003",

"timestamp": "2024-12-01T00:00:00",

"temperature": 0.0,

"humidity": 0.0,

"status": "inactive",

"battery": 0.0

},

(snip)

{

"device_id": "device_010",

"timestamp": "2024-12-10T23:59:00",

"temperature": 0.0,

"humidity": 0.0,

"status": "inactive",

"battery": 0.0

}

]

 device_010のエラーとアクティブ比率を求めてみる。

CREATE TABLE iot_data AS SELECT * FROM read_json('iot_sample_data.json', auto_detect = TRUE);

SELECT

status,

COUNT(*) AS count,

ROUND(100.0 * COUNT() / SUM(COUNT()) OVER (), 2) AS ratio_percentage

FROM iot_data

WHERE device_id = 'device_010'

GROUP BY status;

┌──────────┬───────┬─────────────────┐

│ status │ count │ ratio_percentage │

│ varchar │ int64 │ double │

├──────────┼───────┼─────────────────┤

│ error │ 4743 │ 32.94 │

│ inactive │ 4869 │ 33.81 │

│ active │ 4788 │ 33.25 │

└──────────┴───────┴─────────────────┘

 なるほど、便利ね。状態はランダム生成したので、比率は同じくらいになっている。生のデータじゃないからね。

 ここまで、主にChatGPT o4使ったわけだけど、手元ではPythonの実行すらしていないw 便利な世の中ね。

 SQLite 3.38.0(2022/2/22)からは、JSONを扱えるようだけど、DuckDBのように直接ロードすることはできないみたい。シェルスクリプトとかで処理する場合は、こういうところはアドバンテージあるね。


オリジナル投稿:
DuckDBにJSONを食わせてみる|kinneko|pixivFANBOX
https://kinneko.fanbox.cc/posts/9051307