この記事ではTinyDBというPythonモジュールの使い方について説明します。TinyDBはPythonのみで動作する軽量なドキュメント指向データベースです。
TinyDBはリレーショナルデータベースにおけるsqlite3のような位置付けのモジュールです。データベース全体は一つのファイルに保存されます。公式が提供しているデータベースのファイル形式はJSONだけですが、カスタマイズすればYAMLなどの形式で保存することも可能です。
pydanticなどの、オブジェクトを辞書化するライブラリと組み合わせて使用すると非常に便利です。
インストール
pip
コマンドでインストール可能です。
$ pip install tinydb
基本的な使い方
まずは以下のコードをご覧ください。
from tinydb import TinyDB, Query
with TinyDB("db.json") as db:
User = Query()
db.insert({"name": "John", "age": 22})
print(db.search(User.name == "John"))
#> [{'name': 'John', 'age': 22}]
- データベースの保存先のファイルパスを指定して
TinyDB
のインスタンスを作成するだけで準備完了です。自動でclose
メソッドを実行するためにはwith
構文を使用します。 insert
メソッドに辞書オブジェクトを与えればデータを保存できます。なお、db
をclose
せずともファイルがフラッシュされるようになっています。- データを検索する場合は、
Query
オブジェクトを用いて構築した論理式をsearch
メソッドに入力します。
検索・更新・削除
検索
まず、all
メソッドで全てのデータを取得することができます。
from tinydb import TinyDB, Query
db = TinyDB("db.json")
User = Query()
db.insert(
{
"name": "John",
"age": 22,
"birthday": {
"year": 1999,
"month": 1,
"day": 21,
},
}
)
db.insert(
{
"name": "Bob",
"age": 21,
"birthday": {
"year": 2000,
"month": 2,
"day": 10,
},
}
)
print(db.all())
#> [{'name': 'John', 'age': 22, 'birthday': {'year': 1999, 'month': 1, 'day': 21}}, {'name': 'Bob', 'age': 21, 'birthday': {'year': 2000, 'month': 2, 'day': 10}}]
最上位以外のオブジェクトのフィールドはピリオドでアクセスできます。
print(db.search(User.birthday.year < 2000))
#> [{'name': 'John', 'age': 22, 'birthday': {'year': 1999, 'month': 1, 'day': 21}}]
論理否定・論理積・論理和にはそれぞれ~
, &
, |
記号を使用します。
print(db.search((User.name == "John") & (User.age > 30)))
#> []
更新
更新はupdate
メソッドを使用します。更新するKey-Valueペアを表す辞書を第一引数(fields
引数)に、対象となるオブジェクトを指定するクエリを第二引数(query
引数)に指定します。
db.update({"age": 22}, User.name == "Bob")
print(db.search(User.name == "Bob"))
#> [{'name': 'Bob', 'age': 22, 'birthday': {'year': 2000, 'month': 2, 'day': 10}}]
削除
オブジェクトを削除するにはremove
メソッドを使用します。
db.remove(User.name == "John")
print(db.all())
#> [{'name': 'Bob', 'age': 22, 'birthday': {'year': 2000, 'month': 2, 'day': 10}}]
truncateメソッドで、全てのオブジェクトを削除できます。
db.truncate()
print(db.all())
#> []
データベースをYAML形式で読み書き
公式のStorageクラスの拡張方法に関する説明を参考に紹介します。なお、そのままでは正常動作しなかったため、修正を加えています。また、公式もこの記事も簡易的な実装を紹介するのみで、本格利用する場合は公式のJSONStorage
を参考にきちんと実装するのが良いと思います。
まずはPyYAMLをインストールします。
$ pip install pyyaml
TinyDBのStorage
クラスとPyYAMLを組み合わせて以下のようなサブクラスを作成します。
import yaml
from tinydb import TinyDB, Query, Storage
class YAMLStorage(Storage):
def __init__(self, filename):
self.filename = filename
def read(self):
try:
with open(self.filename) as handle:
data = yaml.safe_load(handle.read())
return data
except BaseException:
return None
def write(self, data):
with open(self.filename, "w+") as handle:
yaml.dump(data, handle)
def close(self):
pass
TinyDBインスタンスの作成時にstorage
引数に上記のクラスを指定すれば、後はJSONと同じように取り扱うことができます。
db = TinyDB("db.yml", storage=YAMLStorage)
User = Query()
db.insert({"name": "John", "age": 22})
print(db.search(User.name == "John"))
#> [{'age': 22, 'name': 'John'}]
バージョン情報
この記事のコードは以下のバージョンのライブラリで検証しました。
- tinydb==4.6.1
- PyYAML==6.0