はじめに
この記事は JSL (日本システム技研) Advent Calendar 2024 - Qiita 6日目の記事です(カレンダー的には7日目です)。
前回の続きでFAST APIを使った簡易CRM実装の続きを記事にします。
今回は、sqlite
とSQLAlchemy
を使ってデータ永続化するに辺りDBとテーブル生成までを記事にします。
FAST APIの公式ドキュメントを参考に進めてきます。
また、こちらの記事を間に書いた関係で、パッケージ管理をpip
からpoetry
に移行しています。
おさらい
環境:
・macOS 12.6 Apple M1 Pro
・Python 3.12.7
現状のフォルダ構成は以下となります。
├── backend
│ ├── app
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ │ ├── __init__.cpython-312.pyc
│ │ │ ├── main.cpython-312.pyc
│ │ │ └── models.cpython-312.pyc
│ │ ├── api
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── main.cpython-312.pyc
│ │ │ ├── main.py
│ │ │ └── routes
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── customer.cpython-312.pyc
│ │ │ │ └── hello.cpython-312.pyc
│ │ │ ├── customer.py
│ │ │ └── hello.py
│ │ ├── core
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ └── db.py
│ │ ├── main.py
│ │ ├── models.py
│ │ └── tests
│ └── requirements.txt
├── poetry.lock
└── pyproject.toml
CustomerをSQLModelへ書き換える
モデルCustomer
をBaseModelからSQLModelへ書きかえます。
SQLModelのインストール
$ poetry add sqlmodel --group dev
from pydantic import BaseModel
class Customer(BaseModel):
id: int
name: str
address: str
↓
from sqlmodel import SQLModel, Field
class Customer(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
address: str = Field(default=None)
table=True
と定義しておくと、SQLModel.metadata.create_all()
した際に自動生成してくれます。
DBとテーブル生成
from sqlmodel import SQLModel, create_engine
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, connect_args=connect_args)
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
from fastapi import FastAPI
from app.api.main import api_router
from app.core.db import create_db_and_tables
app = FastAPI()
@app.on_event("startup")
def on_startup():
create_db_and_tables()
app.include_router(api_router)
@app.on_event("startup")
とすると、実行時のみ関数が呼ばれるようです。
実行してDBとテーブル作成が出来るか確認してみます。
$ uvicorn app.main:app --reload
database.db
が作成されました。
├── app
│ ├── api
│ ├── core
│ └── tests
└── database.db
DBとテーブルが生成されているか確認します。
# sqlite3 database.db
sqlite> .databases
main: /xxx/backend/database.db r/w
sqlite> .table
customer
sqlite> .schema
CREATE TABLE customer (
id INTEGER NOT NULL,
name VARCHAR NOT NULL,
address VARCHAR NOT NULL,
PRIMARY KEY (id)
);
CREATE INDEX ix_customer_name ON customer (name);
まとめ
今回は、SQLModelを使ったモデル定義とFAST APIからDBとテーブル生成するまでを記事にしました。普段は、DjangoによるModel定義とmigrationでらDBとテーブル生成する機会が多いので、SQLModel.metadata.create_all
によってアプリケーション側で生成するのは新鮮でした。
次回は、生成してCustomerモデルへのCRUD機能の作り込みをしていきます。