pythonでsqlite3データベースを簡単に使う
SQLとかわかんないよみたいな方だってデータベースに触れたら世界が変わるかも知れない。わかんないけど。
ほとんどの場合ざっくりと簡単なクエリ発行で事足りる場合が多いので、SQLに詳しい方だって多分楽できるかも。
DBクラスとDBwrapperクラス
ほぼ素に近い状態でsqliteを使うDBクラスと、そのDBクラスを継承して簡単に使えるファンクションを追加したのがDBwrapperクラス。
DBwrapperクラスはDBクラスのファンクションを全部使えるのでとりあえずDBwrapperクラスを取り込んで使えば便利。
たとえば dict型でデータを作って set とか読んでやればDBにデータを挿入・更新できたり get をforで回してやれば1行づつデータが取り出せる。
データの件数も count で取り出せるぞ、手軽だね。
詳しくは以下のコードの デモ を見てほしい。
あと、テーブル作成を簡単にするファンクションは思いつきつつ気力が無くなったので必要があれば色々考えて作ってみてほしい。(SQLを勉強したほうが良い結果でそうだけどね)
コード
import sqlite3
class DB:
def __init__(self, filePath=None):
if filePath != None:
self.filePath = filePath
def open(self, filePath=None):
if filePath != None:
self.filePath = filePath
self.connection = sqlite3.connect(self.filePath)
self.cursor = self.connection.cursor()
def close(self):
self.cursor.close()
self.connection.close()
def fetch(self, sql):
for row in self.cursor.execute(sql):
yield row
def query(self, sql):
self.cursor.execute(sql)
def commit(self):
self.connection.commit()
def rollback(self):
self.connection.rollback()
def __enter__(self):
self.open()
return self
def __exit__(self, exctype, excvalue, traceback):
self.close()
class DBwrapper(DB):
def set(self, tablename, args={}):
if len(args) == 0:
return False
cols = list(args.keys())
vals = []
for col in cols:
if type(args[col]) == str:
vals.append("'%s'" % args[col])
else:
vals.append(str(args[col]))
columns = ",".join(cols)
values = ",".join(vals)
sql = f"replace into {tablename} ({columns}) values ({values})"
self.query(sql)
return True
def get(self, tablename, args={}):
columns = self._getColumns(tablename)
columnNames = ",".join(columns.keys())
if len(args) > 0:
wh = self._keyValue(args)
sql = f"select {columnNames} from {tablename} where {' and '.join(wh)}"
else:
sql = f"select {columnNames} from {tablename}"
for row in self.fetch(sql):
buf = {}
for idx, col in enumerate(columns):
buf[col] = row[idx]
yield buf
def count(self, tablename, args={}):
if len(args) > 0:
wh = self._keyValue(args)
sql = f"select count(*) from {tablename} where {' and '.join(wh)}"
else:
sql = f"select count(*) from {tablename}"
row = self.fetch(sql)
return row.__next__()[0]
def _getColumns(self, tablename):
sql = f"pragma table_info('{tablename}')"
columns = {x[1]: x[2] for x in self.fetch(sql)}
return columns
def _keyValue(self, args={}):
keys = list(args.keys())
wh = []
for key in keys:
if type(args[key]) == str:
wh.append("%s = '%s'" % (key, args[key]))
else:
wh.append("%s = %s" % (key, args[key]))
return wh
"""
ここからデモ
"""
if __name__ == "__main__":
with DBwrapper("hello.db") as db:
""" テーブルの作成 """
sql = """
CREATE TABLE if not exists names
(
"id" INTEGER,
"name" TEXT,
"age" INTEGER,
PRIMARY KEY("id" AUTOINCREMENT)
);
"""
db.query(sql)
"""
テーブル作成や込み入ったクエリの発行には queryやfetchを使う。
ほとんどの場合はwrapperで用意したgetとsetで事足りる(かも)
"""
# sql = "insert into names ('name') values ('Python')"
# db.query(sql)
#
# sql = "insert into names ('name') values ('Sqlite3')"
# db.query(sql)
#
# for row in db.fetch("select * from names"):
# print(row)
""" テーブルにデータを挿入 """
dat = {"id": 1, "name" : "json", "age": 4}
db.set("names", dat)
dat = {"id": 2, "name": "python", "age": 0}
db.set("names", dat)
""" 以下はnameが指定されていないのでnullになってしまうことに注意 """
# dat = {"id": 2, "age": 30}
# db.set("names", dat)
"""
プライマリキーでデータを参照してデータを更新する
(※正しくは削除と挿入)
"""
dat = {"id": 2, "name": "python", "age": 30}
db.set("names", dat)
""" dict型で全件取得 """
for row in db.get("names"):
print(row)
print("---")
""" 条件を指定してdict型でデータ取得する """
dat = {"name": "python"}
for row in db.get("names", dat):
print(row)
""" テーブルのデータ件数を取得する """
print(db.count("names"))
""" コミットとかロールバック """
#db.commit()
db.rollback()
例のごとく簡易版ではあるけれど十分使えると思います。
何か複雑そうに見えるかもしれないけど本当に簡単につかえるのでコピペして遊んでみてね。