7.0 KiB
NoSQL (分散 / ビッグデータ) Databases
FastAPI はあらゆる NoSQLと統合することもできます。
ここではドキュメントベースのNoSQLデータベースである**Couchbase**を使用した例を見てみましょう。
他にもこれらのNoSQLデータベースを利用することが出来ます:
- MongoDB
- Cassandra
- CouchDB
- ArangoDB
- ElasticSearch など。
!!! tip "豆知識" FastAPIとCouchbaseを使った公式プロジェクト・ジェネレータがあります。すべてDockerベースで、フロントエンドやその他のツールも含まれています: https://github.com/tiangolo/full-stack-fastapi-couchbase
Couchbase コンポーネントの Import
まずはImportしましょう。今はその他のソースコードに注意を払う必要はありません。
{!../../../docs_src/nosql_databases/tutorial001.py!}
"document type" として利用する定数の定義
documentで利用する固定のtype
フィールドを用意しておきます。
これはCouchbaseで必須ではありませんが、後々の助けになるベストプラクティスです。
{!../../../docs_src/nosql_databases/tutorial001.py!}
Bucket
を取得する関数の追加
Couchbaseでは、bucketはdocumentのセットで、様々な種類のものがあります。
Bucketは通常、同一のアプリケーション内で互いに関係を持っています。
リレーショナルデータベースの世界でいう"database"(データベースサーバではなく特定のdatabase)と類似しています。
MongoDB で例えると"collection"と似た概念です。
次のコードでは主に Bucket
を利用してCouchbaseを操作します。
この関数では以下の処理を行います:
- Couchbase クラスタ(1台の場合もあるでしょう)に接続
- タイムアウトのデフォルト値を設定
- クラスタで認証を取得
Bucket
インスタンスを取得- タイムアウトのデフォルト値を設定
- 作成した
Bucket
インスタンスを返却
{!../../../docs_src/nosql_databases/tutorial001.py!}
Pydantic モデルの作成
Couchbaseのdocumentは実際には単にJSONオブジェクトなのでPydanticを利用してモデルに出来ます。
User
モデル
まずはUser
モデルを作成してみましょう:
{!../../../docs_src/nosql_databases/tutorial001.py!}
このモデルはpath operationに使用するのでhashed_password
は含めません。
UserInDB
モデル
それではUserInDB
モデルを作成しましょう。
こちらは実際にデータベースに保存されるデータを保持します。
User
モデルの持つ全ての属性に加えていくつかの属性を追加するのでPydanticのBaseModel
を継承せずにUser
のサブクラスとして定義します:
{!../../../docs_src/nosql_databases/tutorial001.py!}
!!! note "備考"
データベースに保存されるhashed_password
とtype
フィールドをUserInDB
モデルに保持させていることに注意してください。
しかしこれらは(*path operation*で返却する)一般的な`User`モデルには含まれません
user の取得
それでは次の関数を作成しましょう:
- username を取得する
- username を利用してdocumentのIDを生成する
- 作成したIDでdocumentを取得する
- documentの内容を
UserInDB
モデルに設定する
path operation関数とは別に、username
(またはその他のパラメータ)からuserを取得することだけに特化した関数を作成することで、より簡単に複数の部分で再利用したりユニットテストを追加することができます。
{!../../../docs_src/nosql_databases/tutorial001.py!}
f-strings
f"userprofile::{username}"
という記載に馴染みがありませんか?これは Python の"f-string"と呼ばれるものです。
f-stringの{}
の中に入れられた変数は、文字列の中に展開/注入されます。
dict
アンパック
UserInDB(**result.value)
という記載に馴染みがありませんか?これはdict
の"アンパック"と呼ばれるものです。
これはresult.value
のdict
からそのキーと値をそれぞれ取りキーワード引数としてUserInDB
に渡します。
例えばdict
が下記のようになっていた場合:
{
"username": "johndoe",
"hashed_password": "some_hash",
}
UserInDB
には次のように渡されます:
UserInDB(username="johndoe", hashed_password="some_hash")
FastAPI コードの実装
FastAPI
app の作成
{!../../../docs_src/nosql_databases/tutorial001.py!}
path operation関数の作成
私たちのコードはCouchbaseを呼び出しており、実験的なPython await
を使用していないので、私たちはasync def
ではなく通常のdef
で関数を宣言する必要があります。
また、Couchbaseは単一のBucket
オブジェクトを複数のスレッドで使用しないことを推奨していますので、単に直接Bucketを取得して関数に渡すことが出来ます。
{!../../../docs_src/nosql_databases/tutorial001.py!}
まとめ
他のサードパーティ製のNoSQLデータベースを利用する場合でも、そのデータベースの標準ライブラリを利用するだけで利用できます。
他の外部ツール、システム、APIについても同じことが言えます。