LoginSignup
16
12

More than 5 years have passed since last update.

Pythonで色々なデータベースをKey-Value Storeとして利用する

Last updated at Posted at 2018-02-12

軽いアプリをサクッと作りたい時、データモデル含めて走りながら決めていく時、「このテキストを、数値を、dictを、そのまま保存・読込したいのに!」と思うことも割と多いのではないかと思います。

そこで、リレーショナルデータベースをバックエンドDBとして使いつつ、コードからはKey-Value Storeのように気軽に使えるようにするライブラリ「Pycoki(Python Compatible Key-value-store Interface for databases:パイコキ)」を作りました。

Github https://github.com/uezo/pycoki
よろしければStarいただけると幸いです!

この記事では、Pycokiの特長と使い方をご紹介します。

特長

  • シンプルで簡単: キー・値を取得・設定することのみに特化することで、手続きとか設定とかを極限まで省きました
  • 互換性: アプリからの使用方法はそのままに、SQLite(デフォルト), MySQL, SQLServer, PostgreSQLをバックエンドのデータベースとして使用することができます。拡張クラスを実装すれば、その他あらゆるデータベースにも対応可能です
  • 名前空間のサポート: キーの他に名前空間を使用できるので、データの種類ごとにデータベースやテーブルを切り替えて参照・保存する必要がありません
  • 相互運用性: オブジェクトの保存・再利用といえばPickleですが、PycokiではJSONとしでデータベースに保存します。そのためPython以外のプログラムから利用することができる上に、JSON型をサポートするデータベースであれば要素の条件を指定した検索も可能です

インストール

Githubのリポジトリからpipコマンド一発でインストールすることができます。

$ pip install git+https://github.com/uezo/pycoki

基本的な使い方

はじめに、パイコキモジュールのstart()を呼び出します。その後のデータの格納、取得、パイコキの終了方法は以下の通りです。

# Pycokiのインポート
import pycoki

# Pycokiの開始
p = pycoki.start("test.db", init_table=True)   #init_table is required for the first access to create data table

# 各種データの格納。json.dumps可能なデータを値として設定可能
p.set("key1", "value1")
p.set("key2", 123.45)
p.set("key3", {"sub_key1": "sub_val2", "sub_key2": 678, "sub_key3": {"dict_key1":"dict_val1", "dict_key2":["array_val1", "array_val2", "array_val3"]}})

# キーを指定した値の取得
print(p.get("key1"))
# dict/listの値の取得(自動でデシリアライズされます)
print(p.get("key3")["sub_key3"]["dict_key2"][1])
# 全データの取得
print(p.get())
# キーの取得
print(p.keys())

# Pycokiの終了
p.close()

実行結果:

value1
array_val2
{'key1': 'value1', 'key2': 123.45, 'key3': {'sub_key2': 678, 'sub_key3': {'dict_key1': 'dict_val1', 'dict_key2': ['array_val1', 'array_val2', 'array_val3']}, 'sub_key1': 'sub_val2'}}
['key1', 'key2', 'key3']

また、パイコキの開始/終了を自動制御し、単に値の設定・取得する方法は以下の通り。内部的にはデータベースに都度接続・切断するため、パフォーマンスは悪いです。

# Quick setter
pycoki.set("key4", "value4", connection_str="test.db")

# Quick getter
val = pycoki.get("key4", connection_str="test.db")
print(val)
value4

MySQLの使用

デフォルトはSQLiteですが、バックエンドはMySQLに切り替えることができます。この機能を使用するにはMySQLdbをあらかじめ導入しておいてください。

# Import Pycoki and MySQL extension
import pycoki
from pycoki.mysql import MySQLKeyValueStore

# Start Pycoki
mysql_conn_str = "host=localhost;user=root;passwd=;db=pycokidb;charset=utf8;"
# p = pycoki.start(mysql_conn_str, kvsclass=MySQLKeyValueStore)
p = pycoki.start(mysql_conn_str, kvsclass=MySQLKeyValueStore, init_table=True, init_params=("pycokidb",))  #init_table/init_paramsは初回のみ

# Set and get data
p.set("key1", "Hello MySQL!")
print(p.get("key1"))

# Finish Pycoki
p.close()
Hello MySQL!

SQL Server / Azure SQL Databaseの使用

SQL Server / Azure SQL Databaseを使用する方法です。pyodbcが必要になります。

# Import Pycoki and SQLDatabase extension
import pycoki
from pycoki.sqldb import SQLDBKeyValueStore

# Start Pycoki
sqldb_conn_str = "DRIVER={ODBC Driver 13 for SQL Server};SERVER=******.database.windows.net;PORT=1433;DATABASE=******;UID=******;PWD=******"
# p = pycoki.start(sqldb_conn_str, kvsclass=SQLDBKeyValueStore)
p = pycoki.start(sqldb_conn_str, kvsclass=SQLDBKeyValueStore, init_table=True)  #init_tableは初回のみ

# Set and get data
p.set("key1", "Hello SQL Server!")
print(p.get("key1"))

# Finish Pycoki
p.close()
Hello SQL Server!

PostgreSQLの使用

PostgreSQLを使用する方法です。psycopg2が必要になります。

# Import Pycoki and SQLDatabase extension
import pycoki
from pycoki.pgsql import PgSQLKeyValueStore

# Start Pycoki
pgsql_conn_str = "postgresql://username:password@hostname:port/pycokidb"

# p = pycoki.start(pgsql_conn_str, kvsclass=PgSQLKeyValueStore)
p = pycoki.start(pgsql_conn_str, kvsclass=PgSQLKeyValueStore, init_table=True)  #init_tableは初回のみ

# Set and get data
p.set("key1", "Hello PostgreSQL!")
print(p.get("key1"))

# Finish Pycoki
p.close()
Hello PostgreSQL!

おわりに

本来的にはNoSQLのエンジンを使えばよいし、ORMもだいぶ助けになると思うのですが、もっと気軽に使えてそこそこ実用にも耐えうるもの、使い慣れたDBや関連他システムのDBと統合できるもの、といったコンセプトで作りました。それにDBにJSON突っ込んでる人、結構いるみたいでしたので...。

最初はdictのインターフェイスをそのままにとも思ったのですが、キー以外に一階層(名前空間)設けたかったのと、dictと同じように使うにはパフォーマンスが出ないため、誤解なきようgetter/setterを介するようにしています。

ユースケースを踏まえてもっと使いやすくしていきたいと思いますので、コメントかGithubのIssueにどしどしご意見いただけると幸いです。

もし気に入っていただけたら、よろしければStarお願いします!
https://github.com/uezo/pycoki

16
12
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
16
12