Redis OM for Python登場:Redis開発を変える直感的なオブジェクトマッピングとFluentクエリ
RedisとPythonのための直感的なオブジェクトマッピングとFluentクエリ
本記事では、Redis向けの新しい開発者中心ライブラリ「Redis OM for Python」をご紹介します。このライブラリは、オブジェクトマッピングやデータ検証など、Redis開発を大きく楽にする強力な機能を備えています。
このプレビューリリースでは、SQLAlchemy、Peewee、Django ORMなどのORM(オブジェクトリレーショナルマッパー)ユーザーにとって馴染み深い宣言的モデルを使ってデータをモデリングできます。
さらに嬉しいことに、すべてのRedis OMモデルはPydanticモデルでもあります。そのため、Pydanticの堅牢で拡張性の高いデータ検証機能をそのまま利用できます。Pydanticモデルを受け入れるPythonライブラリであれば、どこでもRedis OMモデルが動作します。例えばFastAPIと組み合わせれば、APIエンドポイントの入力検証とドキュメント生成を自動的に行うことが可能です。
個人的に特に気に入っているのは、Fluentクエリ式とセカンダリインデックスのサポートです。さらに、同じライブラリ内で非同期処理と同期処理の両方に対応している点も見逃せません。魅力的な機能はまだまだ続きます。
この記事を読み進めると、ライブラリの設計思想や主要機能の舞台裏を学べます。すぐにコードを試したい方は、後半で紹介するスタートガイドチュートリアルをご覧ください。
Redisのための宣言的モデル
通常、開発者はクライアントライブラリ経由でRedisにアクセスし、Redisのデータ構造(Hashなど)を作成した上で、それに対するコマンドを実行します。
多くの方は、リレーショナルデータベースでSQLを書くよりもシンプルだという理由で、このコマンドベースのインターフェースを好みます。しかし、皆さんが最後にSQLを書いたのはいつでしょうか?現代のWebフレームワークを使う開発者の多くは、特に宣言的モデルとともにORMを利用する傾向にあります。
ORMの魅力は、解決したい問題とは無関係な複雑さを取り除いてくれる点にあります。私たちはRedis OMを開発することで、Redisにおいても同じ開発体験を実現できるようにしました。
HashかJSONか、用途に合わせて選択可能
Redis OM for Pythonには、モデル構築の基盤となる2つの基底モデルクラスが用意されています。HashModelとJsonModelです。
オープンソース版Redisのユーザーは、HashModelを使ってデータをHashとして保存できます。一方、RedisJSONモジュールがインストールされている環境や、Redis Enterprise Cloud / Softwareを利用している場合は、JsonModelを使ってデータをJSONオブジェクトとしてネイティブに保存できます。両者の違いについては後述しますが、まずはHashModelから見ていきましょう。
簡潔なモデル定義
以下は、Customerモデルを定義し、それを使ってRedisにデータを保存するRedis OMのコード例です。
※ 実際のコード例は、原文の埋め込みコンテンツまたは公式チュートリアルをご参照ください。
このように簡潔にモデルを定義するだけで、get()やsave()といったメソッドが即座に使えるようになります。内部では、これらのメソッドがRedis Hash上のデータ管理を担っています。
しかし、Redis OMの機能はこれだけにとどまりません。グローバルに一意で、かつソート可能なプライマリキーも自動生成されます。この仕組みは非常に有用なので、詳しく説明しましょう。
グローバルに一意なプライマリキー
Redis OMは、すべてのモデルインスタンスに対して、グローバルに一意なプライマリキーを自動生成します。このプライマリキーを使って、Redisへのデータ保存や取得を行えます。
これらのプライマリキーはグローバルな一意性が保証されているだけでなく、Redisへのリクエストなしに完全にクライアント側で生成される点が特長です。しかも、ソート可能でコンパクトです。これを可能にしているのが、ULID(Universally Unique Lexicographically Sortable Identifier)仕様です。
Redis OMのプライマリキーはULIDを採用しており、python-ulidライブラリによって実装されています。ULID仕様の詳細は公式ドキュメントで確認できます。時刻順に並べられる識別子という発想は、とても面白い仕様です。
永続化機能に加えて、Pydanticによるデータ検証も利用できます。ここからは、検証の仕組みを掘り下げてみましょう。
Pydanticによるデータ検証
Redisとリレーショナルデータベースの大きな違いの一つは、Redisがスキーマを強制しないことです。そのため、あるキーに文字列を書き込んだ後に、同じキーを数値で上書きすることもできてしまいます。これはリレーショナルデータベースよりも柔軟である反面、データ検証の責任がアプリケーション側に委ねられることを意味します。
私たちは、アプリケーションごとに最適な検証手法を各自で考案する負担は不该ないと考えています。そこで、すべてのRedis OMモデルをPydanticモデルとして設計しました。これにより、モデルの型ヒントに基づくPydanticの検証が自動的に働き、カスタムバリデータを含む標準的なPydanticフックで検証ロジックを細かく制御できます。
以下のコード例で、検証の動作イメージをご覧ください。
※ 実際のコード例は、原文の埋め込みコンテンツまたは公式チュートリアルをご参照ください。
もしRedis OM for Pythonが永続化メソッドとデータ検証だけを提供するライブラリだったとしても、それだけでも十分に魅力的です。しかし私たちは、開発者からさらに多くの複雑さを引き受けることを目指しました。そのために必要だったのが、ORMのように表現力豊かなクエリを記述できる仕組みです。次は、そのクエリ機能について説明します。
Fluentクエリ式
ORMの価値は宣言的モデルだけではありません。プライマリキー以外の属性に基づいてデータを検索できるAPIも提供します。「特定の年齢以上の顧客を全員抽出する」「特定の日付より前に登録した顧客を検索する」といったケースを想像してみてください。
標準状態のRedisは、プライマリキーによるデータ取得に非常に優れています。Redis自体が、値としてデータ構造を持つキーバリューストアだからです。しかし、Redisにはクエリ実行やセカンダリインデックスの仕組みが組み込まれていないため、インデックス付きの検索を実現するには、開発者が複雑な方法で自前のインデックスを管理する必要がありました。
ここでも私たちは、この複雑さを引き受けることを選びました。そして、重要なRedisモジュールであるRediSearchの上に、Fluentクエリ式を構築したのです。RediSearchは、Redisに不足していたクエリ機能とインデックス機能を補完する、ソース公開型のモジュールです。
Customerモデルの一部のフィールドにindex=Trueを設定すると、次のようにモデルを使ったクエリが記述できるようになります。
※ 実際のコード例は、原文の埋め込みコンテンツまたは公式チュートリアルをご参照ください。
この式構文には見覚えがあるかもしれません。Peewee、SQLAlchemy、Django ORMのそれぞれの良さを融合させた設計になっています。
埋め込みモデル
Redisで複雑なデータをモデリングしていると、必ずと言っていいほど「埋め込みデータ」を保存したくなる場面が訪れます。例えば、顧客データをRedis Hashで管理している場合、各顧客のHashの中に配送先住所などの情報を持たせたいと考えるでしょう。しかし残念ながら、Redis HashはListやSet、別のHashといったネストされたコンテナを格納できないため、これは実現できません。
ここで威力を発揮するのが、データをネイティブなJSONオブジェクトとして保存する方式です。顧客データをJSONドキュメントとしてモデル化すれば、一人の顧客レコードの中に、任意の構造のデータを自由に埋め込めます。
ただし、RedisはJSONをネイティブにはサポートしていません。まさにこの課題を解決するために、私たちはソース公開型のRedisJSONモジュールを開発しました。RedisJSONを使えば、Redisをドキュメントデータベースとして扱い、複雑なJSONオブジェクトを簡単に保存・検索できるようになります。
Redis OM for Pythonでは、RedisインスタンスにRedisJSONがインストールされていれば、JsonModelクラスを利用できます。このクラスにより、JsonModelの中に別のJsonModelを埋め込むことが可能です。例えば、「顧客が注文の配列を持ち、各注文が商品アイテムの配列を持つ」といった多階層のデータ構造も自然に表現できます。
Redis OM for Pythonでの埋め込みJSONモデルは、以下のように記述します。
※ 実際のコード例は、原文の埋め込みコンテンツまたは公式チュートリアルをご参照ください。
さらに素晴らしいのは、複雑なJSONオブジェクトを柔軟に保存できるだけでなく、Redis OM for Pythonがこうしたネスト構造を認識し、入れ子になったフィールドに対してもクエリ式を書ける点です。
Redis OM for Pythonを試してみよう
私がRedis OM for Pythonにどれほど期待しているか、お伝えできたと思います。現在のPythonエコシステムの優れた要素を結集し、Redis開発者が本来背負う必要のない複雑さを取り除くことに取り組んできました。
興味を持っていただけたなら、ぜひスタートガイドチュートリアルをチェックしてください。Redis OM for Pythonは、私たちが「プレビュー」と呼ぶ非常に初期の段階にあります。完成度が十分でない部分もあれば、バグに遭遇することもあるでしょうし、ドキュメントの整備もこれから進めていく段階です。しかしビジョンは明確です。ぜひ一度触ってみてください。
最後に一言。私たちは宣言的データモデルからスタートしましたが、データモデリングのみならず、その先にも作りたいものがたくさんあります。今後のRedis OMの新機能にもご期待ください。
-
Redis Launchpadとは?Redisをリアルタイムデータプラットフォームとして活用する75以上のサンプルアプリハブ
Redisコミュニティは、Redisの魅力を支える中核的存在です。このコミュニティのおかげで、RedisはStack Overflowの開発者調査において、5年連続で「最も愛されているデータベース」に選ばれました。Redisの人気が高まるにつれ、開発者コミュニティ、業界のバーティカル(垂直分野)、地域を問わず、そのユースケースも拡大し続けています。 コミュニティへの愛情と単一のビジョンのもとでRedisの力を最大限に引き出し、育てていくこと——それが私たちが「Redis Launchpad」を構想した理由です。本日、私たちはRedis Launchpadの公開をお知らせできることを嬉しく思い
-
StrapiにUpstash Redisでサーバーレスキャッシングを導入する方法
プロジェクトを期限内に納品するには、既存の技術をできる限り活用することが重要です。独自実装につながる判断をするたびに、そのソリューションを自前でメンテナンスし続けるコストも考慮しなければなりません。だからこそ、Strapiのようなオープンソースツールは、次のプロジェクトのREST API構築に最適な選択肢となるのです。 Strapiは最先端のヘッドレスCMSです。グラフィカルなインターフェースでスキーマを定義できるため、技術者以外の人でもデータモデリングが可能です。開発チームはバックエンドの実装を気にすることなく、Web・モバイルアプリの構築や新機能の提供に集中できます。何しろ、大規模なオープ