SqlalchemyでDBにデータINSERTしたりSELECTする際の処理速度を早くするための知見をサンプルコードにしました。
Qiitaにも似たような記事はあるのですが、変数名などがおかしくてそのままコピペすると動作しなかったので自分用に書き直したものですが、何かの参考になれば幸いです。
DB作成
まずはデータベースを作成します。DBは簡単なものでsqliteを使います。
使い方は過去記事参照:Pythonでデータベース(DB)を作成・操作できる「sqlite3」の使い方を分かりやすく解説する
ちなみにsqliteはanacondaにデフォルトでインストールされています。
from flask_sqlalchemy import SQLAlchemy from sqlalchemy import create_engine, MetaData from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.schema import Column from sqlalchemy.types import Integer, String import time uri = 'sqlite:///test.db' engine = create_engine(uri) Base = declarative_base() class User(Base): __tablename__ = "user" # テーブル名を指定 #カラム名とデータ型を指定 user_id = Column(Integer, primary_key=True) first_name = Column(String(255)) last_name = Column(String(255)) age = Column(Integer) def full_name(self): # フルネームを返すメソッド return "{self.first_name} {self.last_name}" # テーブル作成 Base.metadata.create_all(engine)
これでtest.dbの中にuserというfirst_name/last_name/ageの3列を持ったテーブルが作成されます。
接続してセッションを作成するのは以下になります。
from sqlalchemy.orm import sessionmaker SessionClass = sessionmaker(engine) session = SessionClass()
# 登録用のサンプルデータを作成 data_list = [] for i in range(1000): data_list.append(["first_a","last_a", i])
基本(一行ずつ挿入)
まずはプログラミングスクールの記事にあるような一行ずつデータをインサートする基本形
# for文で1つずつデータをINSERTする start_default = time.time() for d in data_list: item = User() item.first_name = d[0] item.last_name = d[1] item.age = d[2] session.add(item) session.commit() print(time.time() -start_default)
Bulk Insertで挿入する
#bulk_insert start_bulk = time.time() session.bulk_save_objects( [User(first_name=d[0], last_name=d[1], age=d[2]) for d in data_list], return_defaults=True) session.commit() print(time.time() -start_bulk)
sqlalchemy.coreを使う
sqlalchemyはORMライブラリですが、sqlalchemy.coreを使うことでORMでのサポートを取り外して直にクエリを叩くことが可能になります。その代わりORMにあるロールバック機能などはそぎ落とされています。
# sqlalchemy.coreを使う start_core = time.time() users = [{'first_name':d[0], 'last_name': d[1], 'age': d[2]} for d in data_list] session.execute(User.__table__.insert(), users) session.commit() print(time.time() -start_core)
計測結果
結論としては他の記事にも書かれてはいますが、sqlalchemy.coreが圧倒的に早いという結果になりました。データのINSERT時間で悩んでいる方はsqlalchemy.coreをまず使ってみるのがよさそうです。
・各処理の実行時間
一行ずつ :35.96628475189209
BulkInsert :0.5141918659210205
sqlalchemy.core:0.03986859321594238
参考:https://qiita.com/arkuchy/items/75799665acd09520bed2
参考:https://qiita.com/yukiB/items/d6a70da802cb5731dc01
関連記事:【Python】Flask+SQLAlchemyで「ひとこと掲示板」を作る
関連記事:FlaskによるWebアプリ開発④~SQLAlchemyを使ってデータベースを操作する
コメント