Published

NoSQL (分散 / ビッグデータ) Databases

FastAPI framework, high performance, easy to learn, fast to code, ready for production We just scratched the surface, but you already get the idea of how it all works...

NoSQL (分散 / ビッグデータ) Databases

FastAPI はあらゆる NoSQLと統合することもできます。

ここではドキュメントベースのNoSQLデータベースである**Couchbase**を使用した例を見てみましょう。

他にもこれらのNoSQLデータベースを利用することが出来ます:

  • MongoDB
  • Cassandra
  • CouchDB
  • ArangoDB
  • ElasticSearch など。

!!! tip "豆知識" FastAPICouchbaseを使った公式プロジェクト・ジェネレータがあります。すべて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_passwordtypeフィールドを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.valuedictからそのキーと値をそれぞれ取りキーワード引数として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についても同じことが言えます。