0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SQLAlchemy クエリの実行タイミングと中身①

Posted at

まとめ(結論だけ知りたい人用)

  • SELECT
    問答無用で1メソッドにつき1つクエリを発行し実行します。

  • INSERT

    • autoflushを有効にしている場合
      無駄なクエリを抑制して発行・実行してくれます。

    • autoflushを無効化し、明示的にflushを使う場合
      flush()を実行するタイミングで発行・実行されます。

  • UPDATE

    • autoflushを有効にしている場合
      無駄なクエリを抑制して発行・実行してくれます。

    • autoflushを無効化し、明示的にflushを使う場合
      flush()を実行するタイミングで発行・実行されます。


詳しく知りたい方は記事本文をどうぞ

概要

SQLAlchemyで発行されるCRUDに関するクエリの内容と実行タイミングを見ていきます。
この記事ではSELECT/INSERT/UPDATEについて記載します。

SELECT

下記のコードを実行してみます。

SessionClass = sessionmaker(engine, autoflush=True)
session = SessionClass()

session.query(User).all() # ここでクエリが実行されます。
session.query(User).all() # ここでクエリが実行されます。
session.query(User).all() # ここでクエリが実行されます。

session.close()

実行されるクエリは以下の通りとなります。

SELECT user.id AS user_id, user.name AS user_name, user.email AS user_email FROM user
SELECT user.id AS user_id, user.name AS user_name, user.email AS user_email FROM user
SELECT user.id AS user_id, user.name AS user_name, user.email AS user_email FROM user

全く同じ内容のクエリであっても、問答無用でSELECT文が実行されます。

INSERT

autoflushを有効にしている場合

下記のコードを実行してみます。

SessionClass = sessionmaker(engine, autoflush=True)
session = SessionClass()

user = User(user_id="1", name="John", email="john@example.com")
session.add(user)
user2 = User(user_id="2", name="Johnwick", email="johnwick@example.com")
session.add(user2)

session.commit() # ここでクエリが実行されます。
session.close()

実行されるクエリは以下の通りとなります。

INSERT INTO user (id, name, email) VALUES ('1', 'John', 'john@example.com'),('2', 'Johnwick', 'johnwick@example.com')
COMMIT

INSERT文が1つにまとめられています。

autoflushを無効化し、明示的にflushを使う場合

下記のコードを実行してみます。

SessionClass = sessionmaker(engine, autoflush=False)
session = SessionClass()

user = User(user_id="1", name="John", email="john@example.com")
session.add(user)
session.flush() # ここでクエリが実行されます。

user2 = User(user_id="2", name="Johnwick", email="johnwick@example.com")
session.add(user2)
session.flush() # ここでクエリが実行されます。

session.commit() # ここでクエリが実行されます。
session.close()

実行されるクエリは以下の通りとなります。

INSERT INTO user (id, name, email) VALUES ('1', 'John', 'john@example.com')
INSERT INTO user (id, name, email) VALUES ('2', 'Johnwick', 'johnwick@example.com')
COMMIT

flush()が実行されるタイミングでINSERT文が実行されます。
autoflush=Trueの時に比べて無駄なクエリの発行が行われます。

UPDATA

autoflushを有効にしている場合

以下のコードを実行してみます。

SessionClass = sessionmaker(engine, autoflush=True)
session = SessionClass()

user = User(user_id="1", name="John", email="john@example.com")
session.add(user)

user.email = "johndoe@example.com"
session.add(user)

user.name = "Johndoe"
session.add(user)

session.commit() # ここでクエリが実行されます。
session.close()

実行されるクエリは以下の通りとなります。

INSERT INTO user (id, name, email) VALUES ('1', 'Johndoe', 'johndoe@example.com')
COMMIT

INSERTとUPDATEが統合されて一つのINSERTになっていることが分かります。

autoflushを無効化し、明示的にflushを使う場合

以下のコードを実行してみます。

SessionClass = sessionmaker(engine, autoflush=False)
session = SessionClass()

user = User(user_id="1", name="John", email="john@example.com")
session.add(user)
session.flush() # ここでクエリが実行されます。

user.email = "johndoe@example.com"
session.add(user)
session.flush() # ここでクエリが実行されます。

user.name = "Johndoe"
session.add(user)
session.flush() # ここでクエリが実行されます。

session.commit() # ここでクエリが実行されます。
session.close()

実行されるクエリは以下の通りとなります。

INSERT INTO user (id, name, email) VALUES ('1', 'John', 'john@example.com')
UPDATE user SET email='johndoe@example.com' WHERE user.id = '1'
UPDATE user SET name='Johndoe' WHERE user.id = '1'
COMMIT

flush()を実行するたびにクエリが発行されていることが分かります。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?