Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SQLModel 入門
Search
MIKIO KUBO
July 03, 2025
Programming
0
40
SQLModel 入門
SQLModel 入門
### PydanticとSQLAlchemyの"いいとこ取り"!
MIKIO KUBO
July 03, 2025
Tweet
Share
More Decks by MIKIO KUBO
See All by MIKIO KUBO
API、HTTP、Webhookの初学者向け完全ガイド
mickey_kubo
0
2
Connecting Theory and Practice V
mickey_kubo
0
9
データベースの世界 SQL vs NoSQL
mickey_kubo
0
97
PyMongo入門
mickey_kubo
0
22
Pythonで学ぶSQL入門
mickey_kubo
0
58
AutoGluon 時系列予測モデルの解説
mickey_kubo
1
45
AutoGluon Tabularモデル入門
mickey_kubo
1
21
AutoGluon: State-of-the-Art Automated Machine Learning
mickey_kubo
0
61
AutoGluon: State-of-the-Art Automated Machine Learning (English)
mickey_kubo
1
22
Other Decks in Programming
See All in Programming
Jakarta EE Meets AI
ivargrimstad
0
260
11年かかって やっとVibe Codingに 時代が追いつきましたね
yimajo
0
150
はじめてのWeb API体験 ー 飲食店検索アプリを作ろうー
akinko_0915
0
160
「App Intent」よくわからんけどすごい!
rinngo0302
1
120
型で語るカタ
irof
0
800
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
450
マッチングアプリにおけるフリックUIで苦労したこと
yuheiito
0
240
Claude Code で Astro blog を Pages から Workers へ移行してみた
codehex
0
140
What's new in AppKit on macOS 26
1024jp
0
170
Streamlitで実現できるようになったこと、実現してくれたこと
ayumu_yamaguchi
2
210
PHPUnitの限界をPlaywrightで補完するテストアプローチ
yuzneri
0
270
テスターからテストエンジニアへ ~新米テストエンジニアが歩んだ9ヶ月振り返り~
non0113
2
240
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Embracing the Ebb and Flow
colly
86
4.8k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
47
9.6k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
The World Runs on Bad Software
bkeepers
PRO
70
11k
Navigating Team Friction
lara
187
15k
RailsConf 2023
tenderlove
30
1.2k
Site-Speed That Sticks
csswizardry
10
720
Being A Developer After 40
akosma
90
590k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Bash Introduction
62gerente
613
210k
Transcript
SQLModel 入門 Pydantic とSQLAlchemy の" いいとこ取り" ! 1
このスライドで学べること SQLModel とは何か? なぜ便利なのか? これまでのデータベース操作の 課題点 SQLModelを使った 基本的なCRUD 操作 (作成,
読取, 更新, 削除) リレーションシップ(テーブル間の連携)の扱い方 FastAPIと連携した実践的なWebアプリケーション開発 ゴール:このスライドだけでSQLModel の基本をマスターし、アプリ開発に活かせるようになる! 2
SQLModel ってなに? 一言でいうと、Pydantic と SQLAlchemy を融合させたライブラリです。 ライブラリ 役割 Pydantic データのバリデーション(検証)と設定管理。型ヒントでデータ構造を定義。
SQLAlchemy Pythonでデータベースを操作するためのORM (Object-Relational Mapper)。 **SQLModel** は、この2つの長所を組み合わせることで、**1つのクラス定義**で**データベース のテーブル構造**と**APIなどで使うデータモデル**の両方を表現できるようにしたものです。 開発者は、WebフレームワークFastAPIの作者でもある Sebastián Ramírez (tiangolo) 氏です。 3
これまでの課題:モデル定義の重複 SQLModelがない世界では、データベース用のモデルと、APIでやり取りするためのデータモデルを 別々に定義する必要がありました。 # データベース用 (SQLAlchemy) class UserDB(Base): __tablename__ =
'users' id = Column(Integer, primary_key=True) name = Column(String) email = Column(String) # API用 (Pydantic) class UserSchema(BaseModel): id: int name: str email: str 似たような定義が2つあり、 コードが冗長になる。 片方を修正したら、もう片方も修正する必要があり、 メンテナンスが大変。 4
SQLModel が解決すること:DRY (Don't Repeat Yourself) SQLModelを使えば、モデル定義は たった1 つで済みます。 # SQLModelなら、これでOK!
from sqlmodel import SQLModel, Field class User(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str email: str SQLModel を継承し、Pydanticのように型ヒントでクラスを定義します。 table=True をつけることで、このクラスがデータベースのテーブル定義でもあることを示し ます。 コードがシンプルになり、 バグが減り、 開発効率が大幅に向上します! 5
準備をしよう:インストール まずは、必要なライブラリをインストールします。このスライドのコードは sqlmodel だけで動作し ます。 # ターミナルで実行 pip install sqlmodel
もし、FastAPIと連携するWebサーバーを動かす場合は、以下もインストールします。 ```bash pip install "fastapi[all]" ``` 6
Step 1: モデルを定義する Hero (ヒーロー)という情報を持つテーブルを作成してみましょう。 heroes.py from typing import Optional
from sqlmodel import Field, SQLModel # SQLModelを継承してモデルクラスを作成 # "table=True" で、これがDBのテーブルに対応することを示す class Hero(SQLModel, table=True): # カラム(属性)を定義 # id: 主キー(primary_key=True)。データ作成時はNoneでもOK id: Optional[int] = Field(default=None, primary_key=True) # name: 文字列型。index=Trueで検索が高速に name: str = Field(index=True) # secret_name: 文字列型 secret_name: str # age: 整数型。NoneでもOK。index=True age: Optional[int] = Field(default=None, index=True) 7
Step 2: データベースエンジンを作成する データベースとの接続を管理する「エンジン」を作成します。 ここでは、手軽なSQLiteを使います。(ファイルベースのDB) database.py from sqlmodel import create_engine
# SQLiteデータベースファイルの名前 sqlite_file_name = "database.db" # データベースURL sqlite_url = f"sqlite:///{sqlite_file_name}" # データベースエンジンを作成 # echo=Trueにすると、実行されたSQLクエリがコンソールに表示される engine = create_engine(sqlite_url, echo=True) 8
Step 3: テーブルを作成する 定義したモデル( Hero クラス)を元に、データベース内にテーブルを物理的に作成します。 main.py from sqlmodel import
SQLModel # 他のファイルからimport from database import engine from models import Hero # 先ほど定義したHeroクラス def create_db_and_tables(): # Heroモデルを含む、SQLModel.metadataに登録された # 全てのテーブルを作成する SQLModel.metadata.create_all(engine) # この関数を一度だけ実行すればテーブルが作られる if __name__ == "__main__": create_db_and_tables() print("データベースとテーブルが作成されました。") 9
Step 4: データを作成する (Create) Session を通じてデータベースと対話します。 Session は、DB操作の一連のまとまり(トランザク ション)を管理します。 main.py
# ... (import文は省略) ... from sqlmodel import Session def create_heroes(): # モデルのインスタンスを作成 hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson") hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador") hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48) # "with"構文でSessionを作成。ブロックを抜けると自動でクローズされる with Session(engine) as session: # 作成したインスタンスをセッションに追加 session.add(hero_1) session.add(hero_2) session.add(hero_3) # データベースに変更を保存(確定) session.commit() 10
Step 5: データを読み取る (Read) select() 関数でクエリを作成し、 session.exec() で実行します。 main.py #
... (import文は省略) ... from sqlmodel import select def select_heroes(): with Session(engine) as session: # Heroテーブルから全件取得するクエリを作成 statement = select(Hero) # クエリを実行し、結果を取得 heroes = session.exec(statement).all() # all()で全件をリストとして取得 for hero in heroes: print(hero) print("-" * 20) # 条件を指定して読み取る (where) statement_filtered = select(Hero).where(Hero.name == "Spider-Boy") hero = session.exec(statement_filtered).first() 11
Step 6: データを更新する (Update) 1. 更新したいデータをまず 読み取ります。 2. オブジェクトの属性値を変更します。 3.
セッションに追加して commit します。 main.py def update_hero(): with Session(engine) as session: # 更新対象のデータを取得 statement = select(Hero).where(Hero.name == "Spider-Boy") hero_to_update = session.exec(statement).one() # 1件だけ取得 # 属性値を変更 hero_to_update.age = 16 print("Updated hero (before commit):", hero_to_update) # セッションに追加してcommit session.add(hero_to_update) session.commit() # DBから最新の状態をオブジェクトに反映 12
Step 7: データを削除する (Delete) 1. 削除したいデータをまず 読み取ります。 2. session.delete() で削除対象を指定します。
3. commit して変更を確定します。 main.py def delete_hero(): with Session(engine) as session: # 削除対象のデータを取得 statement = select(Hero).where(Hero.name == "Deadpond") hero_to_delete = session.exec(statement).first() if hero_to_delete: # データを削除 session.delete(hero_to_delete) session.commit() print("Deleted hero:", hero_to_delete) else: print("Hero not found.") 13
発展: リレーションシップ (1 対多) チーム(Team)とヒーロー(Hero)の関係を定義してみましょう。1つのチームに複数のヒーローが所属 します。 from typing import List,
Optional from sqlmodel import Field, Relationship, SQLModel class Team(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) name: str = Field(index=True) headquarters: str # "heroes"はこのチームに所属するHeroのリスト # back_populatesでお互いの関係性を紐付ける heroes: List["Hero"] = Relationship(back_populates="team") class Hero(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) name: str = Field(index=True) secret_name: str age: Optional[int] = Field(default=None, index=True) # team_id: 外部キー。Teamテーブルのidを参照 team_id: Optional[int] = Field(default=None, foreign_key="team.id") # "team"はこのヒーローが所属するTeamオブジェクト team: Optional[Team] = Relationship(back_populates="heroes") 14
まとめ SQLModel は、Pydantic とSQLAlchemy の強力な機能をシンプルにまとめたライブラリ。 モデル定義を1 つに集約でき、DRYなコーディングが可能になる。 SQLModel , Field
, create_engine , Session , select が基本要素。 基本的なCRUD 操作 -Create(作成)、Read(読み取り)、Update(更新)、Delete(削除)- から リレーションシップまで直感的に扱える。 特にFastAPI との相性は抜群で、堅牢で効率的なWeb APIを素早く構築できる。 今日からあなたのPythonプロジェクトにSQLModelを取り入れてみましょう! 公式ドキュメント: https://sqlmodel.tiangolo.com/ 15
Q & A ご清聴ありがとうございました。 16