【Python】pipでインストールするデータベースLMDB ~ インプロセスデータベース
データベースをインストールしないデータベース(?)
-
を使うには、MySQL をインストールする必要がある。MySQL -
を使うには、PostgreSQL をインストールする必要がある。PostgreSQL -
を使うには、Redis をインストールする必要がある。Redis -
を使うには、CockroachDB をインストールする必要がある。CockroachDB
当たり前とはいえ、プログラミング言語のみで完結しないのはよく考えると面倒ではないか🤔。
データベースをインストールして設定する手間、データベースに於けるユーザー管理の手間、データベースとの通信の手間。縦令それが苦ならざるとも、これら全てが省略できるというならば、事情によっては省略したいだろう。
そこで、pip
でインストールできるデータベース「lmdb
」があったので紹介。
導入
pip
コマンドで入手する。
pip install lmdb
使い方
プログラムは次のものを改変した。
# https://github.com/jnwatson/py-lmdb/blob/master/examples/address-book.py
import lmdb
def main():
''' create a database environment '''
# db = lmdb.open(
db_env: lmdb.Environment = lmdb.Environment(path = 'sample_db', max_dbs = 10)
''' create sub-databases '''
home_db: lmdb._Database = db_env.open_db(key = b'home')
business_db: lmdb._Database = db_env.open_db(key = b'business')
''' write new data '''
with db_env.begin(write = True) as write_transaction:
write_transaction.put(db = home_db, key = b'mother', value = b'098-7654-3210')
write_transaction.put(db = home_db, key = b'father', value = b'012-3456-7890')
write_transaction.put(db = business_db, key = b'vendor', value = b'086-4209-7531')
write_transaction.put(db = business_db, key = b'manager', value = b'013-5790-2468')
''' read data '''
with db_env.begin() as read_transaction:
home_cursor: lmdb.Cursor = read_transaction.cursor(db = home_db)
business_cursor: lmdb.Cursor = read_transaction.cursor(db = business_db)
for key, value in home_cursor:
print(key, value)
for key, value in business_cursor:
print(key, value)
if __name__ == "__main__":
main()
> python main.py
b'father' b'012-3456-7890'
b'mother' b'098-7654-3210'
b'manager' b'013-5790-2468'
b'vendor' b'086-4209-7531'
実行後、sample_db
というフォルダーが生成される。これがデータベースに該当する。
> type .\sample_db\data.mdb
����
����
���business
0home ���business
0home���
father012-3456-7890
mother098-7654-3210���business0home���
father012-3456-7890
mother098-7654-3210���
manager013-5790-2468
vendor086-4209-7531���(
(
���
father012-3456-7890
mother098-7654-3210
���
manager013-5790-2468
vendor086-4209-7531�
��((
���
manager013-5790-2468
vendor086-4209-7531�
���(
(
それらしいデータが認められる。
配布もできる
pyinstaller
を使うと、lmdb
という「
pip install pyinstaller
仮想環境にpyinstaller
を導入した際の使い方はこちらの記事から。
なお「仮想環境にlmdb
をインストールした場合」、「同じ仮想環境にpyinstaller
をインストール」しなければならない。lmdb
のない環境にインストールしたpyinstaller
で実行ファイルにすると、lmdb
が見つからないというエラーが出る。環境は一致させること。
pyinstaller main.py
コンパイル後、build
とdist
という二つのフォルダーが生成される。そのうち、配布用となるのはdist
の方となる。
今回はdist/main/main.exe
というファイルができた。これを実行すると、先と同様、データベースとしてsample_db
というフォルダーが生成される。
> .\dist\main\main.exe
b'father' b'012-3456-7890'
b'mother' b'098-7654-3210'
b'manager' b'013-5790-2468'
b'vendor' b'086-4209-7531'
用語:インプロセスデータベース
lmdb
があるが、sled
というものがある。こちらも使い勝手はlmdb
とほぼ同じであり、
このようなデータベースに合致する概念がどれなのか、浅学者の私には分別覚束ぬが、「インプロセスデータベース」が近いように思えた。システムアーキテクト試験(令和
組込みシステムで
を用いるときには,通信のオーバヘッド,通信負荷の発生を防ぐこと,必要なメモリ容量をリソース制限内に抑えることなどを目的としてインプロセスデータベースを用いることがある。このインプロセスデータベースの説明として,適切なものはどれか。 DBMS
正答はこのような選択肢であった。
データベースエンジンはライブラリ形式で提供され,アプリケーションプログラムとリンクされて同一メモリ空間で動作する。
lmdb
はsled
はlmdb
もsled
も、データベースに当るファイルを読み込んでいるため、恐らくこれがプログラムと同じメモリー上での動作に該当すると見える。
SQLite
種明かしをしよう。わざわざlmdb
をインストールせずとも、sqlite3
というモジュールが搭載されている。
これもまた先述のものと同様、「
# https://docs.python.org/ja/3.13/library/sqlite3.html
import sqlite3
# connect or create db file
db_conn = sqlite3.connect(database = 'sample.db')
# cursor
db_cursor = db_conn.cursor()
# create table
db_cursor.execute("CREATE TABLE movie(title, year, score)")
# select table name → fetch
table_name = db_cursor.execute("SELECT name FROM sqlite_master").fetchone()
print(f'table name: {table_name}')
# insert data
db_cursor.execute(
'''
INSERT INTO movie VALUES
('Monty Python and the Holy Grail', 1975, 8.2),
('And Now for Something Completely Different', 1971, 7.5)
'''
)
# commit
db_conn.commit()
# select score → fetch
score = db_cursor.execute("SELECT score FROM movie").fetchall()
print(f'score: {score}')
> python .\tutorial.py
table name: ('movie',)
score: [(8.2,), (7.5,)]
> type .\sample.db
SQLite format 3@ .�)
��<YtablemoviemovieCREATE TABLE movie(title, year, score)
���8aAnd Now for Something Completely Different�@-KMonty Python and the Holy Grail�@ ffffff
DuckDB
更に、標準ではないものの、
pip install duckdb
CREATE TABLE
文に於いてデータ型を省略できない。寧ろデータ型を省略できることが疑問ではあった。
# https://duckdb.org/docs/stable/clients/python/overview#persistent-storage
import duckdb
def main():
with duckdb.connect('sample.db') as db_conn:
# create table
db_conn.sql('CREATE TABLE movie (title VARCHAR(255), year INTEGER, score FLOAT)')
# insert data
db_conn.sql(
'''
INSERT INTO movie VALUES
('Monty Python and the Holy Grail', 1975, 8.2),
('And Now for Something Completely Different', 1971, 7.5)
'''
)
# show table
db_conn.table('movie').show()
if __name__ == "__main__":
main()
> python .\main.py
┌────────────────────────────────────────────┬───────┬───────┐
│ title │ year │ score │
│ varchar │ int32 │ float │
├────────────────────────────────────────────┼───────┼───────┤
│ Monty Python and the Holy Grail │ 1975 │ 8.2 │
│ And Now for Something Completely Different │ 1971 │ 7.5 │
└────────────────────────────────────────────┴───────┴───────┘
記述量も少ない上に、表示が非常に分かりやすい。
> type .\sample.db
.�'���DUCK@v1.2.27c039464e4w���?�8-�\�`����������������1,��]J��������dcddfmaini����cddesamplefmaini�movie�ddtitleed��gh��dyeared
��gh��dscoreed��gh������ed��������e���fg����defd��ghdefgAnd Now Monty Py���*������edefd��ghdefg����������defde`��ghdefg�de����de���������edefd��ghdefg����������defdeh��ghdefg�de�@���de33A��������edefd��ghdefg����������dddefgAnd Now Monty Py���*����edefde�HYLL������ddefg�de����de�������edefde�HYLL������ddefg�de�@���de33A������edefde�HYLL��������������ede��e������defd����������d��������es��d��������e���g������������������Ү`=�k�IYIAnd Now for Something Completely DifferentMonty Python and the Holy Grail��33A�@
本記事のまとめ
本記事で紹介した四つのインプロセスデータベースについて、その特徴を表にまとめて跋文に代え、筆を置くこととする。
言語 |
|
データ形式 | |
---|---|---|---|
|
|||
|
|||
など |
表形式 | ||
︙ |
表形式 |
Discussion