【図解】SQLAlchemyのfirst, one, scalarの違い

2020年1月20日

当サイトはPR広告を利用しています。

SQLAlchemyにはallをはじめとして多くのクエリーが存在します。その中でもfirst, one, scalarは動作が似ており、きちんと区別して使えている人は少ないです。

そこでこの記事では各クエリーの違いを解説します。

first

クエリによって取得できる全ての行のうち先頭の行だけを取得します。もしクエリによって一つも行が取得できなかった場合にはエラーは発生せず、Noneが返されます

クエリが2つ以上のテーブルを結合するものであれば、結合された状態の行が一つだけ返ってきます。

使い所

order_by句を使ってあるカラムの並びによって並び替えた後に先頭の行を取得したい時などに使えます。例えば、レコードの作成順番でのソート(並び替え)とあわせてfirstを使うことで、最も最近作成されたレコードのみを取得することができます。

one

一行だけの取得を期待し、一行だけを取得するためのクエリです。

もしクエリによって一つも行が取得できなかった場合には"NoResultFound"エラーが発生します。複数行返された時には"MultipleResultsFound"エラーが発生します。

使い所

必ず取得対象が一つしか存在しないようWHERE句(SQLAlchemyで言うfilter)で絞りこむことと同時に使うことが多いです。

また、一つも行を取得できなかったときや複数行取得した時にエラーを発生させる性質からテスト用コードにもよく使われます。

scalar

クエリによって最初に取得できた行の最初の要素を返します。複数行取得できてしまったらoneと同じく"MultipleResultsFound"エラーが発生します。

取得結果がまだ少し分かりにくいと思いますのでscalarを使って値を取得した結果の例を公式サイトから抜粋します。

>>> session.query(Item).scalar()
<Item>
>>> session.query(Item.id).scalar()
1
>>> session.query(Item.id).filter(Item.id < 0).scalar()
None
>>> session.query(Item.id, Item.name).scalar()
1

特に注目して欲しいのが最後の例です。コードではItemテーブルのidとItemテーブルのnameを指定していますが、最初に指定された要素はid(Item.id)のため、1という値のみが返されています。

これは行として情報を取得するone, firstと要素を取得するscalarの大きな違いです。

ついでにoneと比較してみましょう。

# 注意:idカラムとnameカラムを持つUserテーブル作成してから以下の作業を行っています。

user_id = session.query(User.id).one()
print(user_id)  # 出力結果:(1,)
print(type(user_id))  # 出力結果:<class 'sqlalchemy.util._collections.result'>

user_id = session.query(User.id).scalar()
print(user_id)  # 出力結果:1
print(type(user_id))  # 出力結果:<class 'int'>


user = session.query(User.id, User.name).one()
print(user)  # 出力結果:(1, 'ed')
print(type(user))  # 出力結果:<class 'sqlalchemy.util._collections.result'>

user = session.query(User.id, User.name).scalar()
print(user)  # 出力結果:1
print(type(user))  # 出力結果:<class 'int'>

使い所

scalarは要素を返します。そのため、ある行のある要素を一つだけ取得したい場合に利用すると、取得後の記述をシンプルにできます。

全体まとめ

3つのクエリの違いをイメージすると以下のようになります。

複数行が取得できてもエラーを起こさず先頭行だけ返すfirst。

取得行数が0でも複数でもエラーを発生させてしまう厳しいone。

行ではなく要素を返すスマートなscalar。

それぞれのクエリの特徴を理解し、適切に使い分けたコーディングをこころがけましょう。

参考サイト

Query API — SQLAlchemy 1.3 Documentation

直近でおすすめの本

直近十数冊読んだ中で一番おすすめの本です。

人が行動をするに至るまでのステップを科学的に分析した上で、その結果を習慣と紐付けて解説してくれている本です。

悪い習慣を断ち、良い習慣を継続する方法を詳細に説明してくれています。習慣が人を作っているので、この本の内容を実践できれば人生を大きく好転させられる気がしました。

この本の最初の方に説明があるのですが、複利という考え方があり毎日1パーセントだけの増加でもそれが続くととてつもない倍率になります。これは投資でよく用いられる概念ですが、良い習慣は未来への投資なので習慣にもあてはまります。良い習慣を身に付けるのは早ければ早いほど良いです。

私はまず長時間YouTubeを見てしまう習慣を断って、直近の業務に役立つITの勉強を習慣として身に付けよう思います。

PythonSQLAlchemy

Posted by ラプラス