まとめ(結論だけ知りたい人用)
-
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()を実行するたびにクエリが発行されていることが分かります。