Python SQL

【Python】SqlalchemyでのINSERT処理を高速化する方法まとめ

この記事は約6分で読めます。

 

 

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を使ってデータベースを操作する

 

コメント

タイトルとURLをコピーしました