MicroPython的午睡(110) ESP32版、btree + json が一番お楽?

Joseph Halfmoon

前回、MicroPythonで使えるキーバリュー型のデータベースbtreeを使用。いつものPythonの辞書型と似た操作方法でお楽です。ただ一点メンドクセーのが、「bytes型ライクな」オブジェクトでないと格納できない制限です。直接格納できないデータがあったときにどうするのがお楽か。やっぱりJSON化がいいんじゃない。

※「MicroPython的午睡」投稿順 Indexはこちら

btreeデータベース + ujsonシリアル化

前回使用してみたbtreeの日本語マニュアルページが以下です。

btree — 単純な BTree データベース

Pythonでいつもお世話になっている辞書型のオブジェクトとほとんど似た操作方法でマイコンのFlash上のファイルシステムにおかれたデータベースにアクセス可能です。マイコンの電源を切ってもデータは「永続」であります。いろいろあれやこれやと格納しておきたいデータが目白押し。しかし、上記のマニュアルページから一か所引用させていただきます。

辞書型との大きな違いは、キーと値の両方が bytes 型ライクなオブジェクトでなければならないことです

浮動小数点型の数値とか、いろいろな型のデータが詰まったリストとか、辞書などの構造をもったデータなどはどうするのがよろしかろう?データベースへ入力する際に何かバイト列にみえるような出力に「シリアル化」するのが宜しかろうと思いました。フルPythonでは伝統のpickleなども候補かなと思ったですが、MicroPythonにはpickleないのね。であればいつもお世話になっておりますJSON使うのが確実かと。MicroPythonのujson(呼び出すときはjsonでよし)の日本語マニュアルページが以下に。

ujson — JSON のエンコードとデコード

btreeデータベースに格納する際にJSONにシリアライズ、データベースから取り出した際にはデシリアライズすればOKとな。

ESP32_BtreeJsonSave.py

まずは動作確認用のDBへの書き込みスクリプトです。前回の素のbtreeでは直接書きこめないリスト(浮動小数含む)や辞書(浮動小数含む)などの構造をもったデータをJSON化して書き込んでみてます。簡単。

import btree
import json

def openDB(fnam):
    try:
        f = open(fnam, "r+b")
    except OSError:
        f = open(fnam, "w+b")
    return f

def main():
    print("ESP32, store list, dict to btree.")
    fil = openDB("tLIST.db")
    db = btree.open(fil)

    listSample = [1.77, 3.45, "abc"]
    dicSample = {'key1':123.4, 'key2':"xyz"}

    db[b"listSample"] = json.dumps(listSample)
    db[b"dicSample"] = json.dumps(dicSample)
    db.flush()
    db.close()
            
if __name__ == "__main__":
    main()
ESP32_BtreeJsonLoad.py

続いて上記で書き込まれたデータベースから、リスト構造、辞書構造をそれぞれ読み出す実験用スクリプトが以下に。

import btree
import json

def openDB(fnam):
    try:
        f = open(fnam, "r+b")
    except OSError:
        f = open(fnam, "w+b")
    return f

def main():
    print("ESP32, load list and dictionary from btree.")
    fil = openDB("tLIST.db")
    db = btree.open(fil)
    
    listSample = json.loads(db[b"listSample"])
    dicSample = json.loads(db[b"dicSample"])
    print(listSample)
    print(dicSample)
    db.close()
            
if __name__ == "__main__":
    main()
実行結果

JSON化されたオブジェクトが、データベースの1項目として格納されているので、必要なところだけ出し入れするのが便利かと。実際読み出し用の実験コードを走らせたところが以下に。Restored

やっぱJSONはお楽。

MicroPython的午睡(109) ESP32版、btreeモジュールで連想配列永続化? へ戻る

MicroPython的午睡(111) ESP32版、乱数をdequeにつめて非同期タスク へ進む