2026年5月5日に更新された「feed range query fix」は、Azure SDK for Pythonのazure-cosmosで、Azure Cosmos DBのquery_items(feed_range=...)を使ったページングと継続トークンの扱いをより正確にするための変更です。結論から言うと、公開APIの書き換えは不要ですが、feed_range付きクエリ、partition_key付きクエリ、継続トークンを保存して再開する処理、複数Pod・複数プロセスでSDKバージョンが混在する環境は確認が必要です。PR概要では「public API changes」はない一方、継続トークンの内部形式と再開時の挙動に関わる変更が説明されています。(GitHub)
Azure SDKのfeed range query fixで何が変わったのか
今回の変更は、Azure SDK全体というより、Azure SDK for Pythonに含まれるAzure Cosmos DB向けライブラリazure-cosmosのクエリ処理に関するものです。主な対象は、ContainerProxy.query_items()でfeed_rangeやpartition_keyを指定してページングする処理です。
Microsoft LearnのAPIリファレンスでも、query_items()にはfeed_range、partition_key、max_item_count、continuation_token_limitなどのクエリ制御パラメーターが用意されています。feed_rangeはクエリ対象範囲を定義するための値で、max_item_countは列挙操作で返す最大アイテム数を指定する項目です。(Microsoft Learn)
今回のPRで整理されている変更点は、大きく分けて次の2つです。
| 変更点 | 内容 | 主に影響する利用者 |
|---|---|---|
query_items(feed_range=...)のページング修正 | パーティション分割後の再開や、複数の物理パーティションにまたがるfeed rangeでのページングを正しく扱う | feed rangeを使って並列スキャン、範囲指定クエリ、継続取得をしている開発者 |
query_items(partition_key=...)の内部トークン経路統一 | full partition key指定時の継続トークン処理を、feed range側と同じ内部フレームワークに寄せる | partition key指定クエリの継続トークンを保存・共有しているシステム |
重要なのは、メソッド名や引数の使い方が変わる更新ではない点です。アプリケーションコードを一斉に書き換えるよりも、継続トークンをどこで保存し、どのSDKバージョンのプロセスが再利用しているかを点検することが優先されます。
対応が必要なケースと不要なケース
すべてのAzure SDK利用者が対応すべき変更ではありません。影響を受けるかどうかは、Cosmos DBで「ページングされたクエリ結果を途中から再開しているか」「feed rangeを使っているか」「SDKバージョンが混在する可能性があるか」で判断できます。
| 利用状況 | 対応優先度 | 確認すべきこと |
|---|---|---|
query_items(feed_range=...)を使っている | 高 | 古い継続トークンからの再開、重複処理への耐性、SDK更新計画 |
| feed rangeを使い、結果取得を複数ページに分けている | 高 | max_item_countどおりの件数が常に返る前提になっていないか |
| 取得途中のcontinuation tokenをDBやキューに保存している | 高 | 旧SDK・新SDK間で同じトークンを再利用していないか |
query_items(partition_key=...)で継続トークンを使う | 中 | 環境変数AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PKの設定状況 |
単純なread_item()やcreate_item()のみ | 低 | 通常は今回の変更の直接影響は小さい |
| クロスパーティションの集計クエリ中心 | 低〜中 | 継続トークンのサポート範囲を公式ドキュメントで再確認 |
Cosmos DBのクエリ結果は、RU不足、応答サイズ、実行時間などの理由で複数ページに分割されることがあります。正確な結果を得るには、追加ページがなくなるまで進める必要があります。さらに、公式ドキュメントでは、同じSDKバージョンを使っている限り継続トークンは期限切れにならないと説明されています。これは裏を返すと、SDKバージョンをまたいで永続化トークンを扱う運用では、互換性確認が重要になるということです。(Microsoft Learn)
feed rangeページング修正の実務上の意味
今回の修正で最も重要なのは、物理パーティションの分割後にfeed_range付きクエリを再開するケースです。
Azure Cosmos DBでは、データ量やスループットに応じて物理パーティションが分割されることがあります。アプリケーションがfeed rangeを使ってクエリ結果をページングしている最中にパーティション分割が起きると、以前の範囲が複数の物理パーティションにまたがる状態になります。
PR概要では、このようなsplit/resumeシナリオや、複数物理パーティションに重なるfeed rangeでのページセマンティクスを修正すると説明されています。さらに、構造化された継続状態、feed rangeの識別情報、サブレンジごとのバックエンド継続キューを導入する内容が示されています。(GitHub)
実務では、次のような処理が影響を受けやすいです。
| よくある処理 | 起きやすい問題 | 見直しポイント |
|---|---|---|
| 大量データをfeed range単位で並列スキャン | 分割後の再開で重複・欠落・ページサイズの乱れが起きる可能性 | 処理済みIDの記録、再実行可能な設計 |
| continuation tokenを保存して夜間バッチを再開 | 旧トークン再開時に前の位置から読み直す可能性 | 重複を許容する集計・書き込みにする |
max_item_countを厳密なページ件数として扱う | 実際の返却件数が期待とずれる | 「最大件数」であり「保証件数」ではない前提にする |
| 途中失敗後に同じトークンで再開 | まれに同じ行を再処理する可能性 | idempotentな処理にする |
特に、ページング結果をそのまま外部システムへ書き込むバッチでは注意が必要です。たとえば、Cosmos DBから読み出したデータをCSVに追記するだけの処理では、再開時に重複行が混ざる可能性があります。読み出したidとパーティションキーを処理済みテーブルに記録する、出力先でUPSERTする、集計処理では同じイベントを二重加算しない仕組みにするなど、重複耐性を持たせてください。
旧continuation tokenの扱いで注意すべき点
PR概要では、feed rangeパス上のレガシーなopaque tokenは、リスクのある解釈を避けるため「start-fresh」として扱う方針が示されています。その結果、古いトークンから再開した場合、以前の位置より前から読み直される可能性があり、クライアント側では再処理を許容する必要があると説明されています。(GitHub)
ここでの判断基準はシンプルです。
保存済みトークンがある場合
バッチ、ワーカー、APIサーバーがcontinuation tokenを永続化しているなら、SDK更新前後で次を確認します。
| 確認項目 | 推奨対応 |
|---|---|
| 古いSDKで発行したトークンを保存しているか | 更新後の初回再開で重複読み取りが起きても問題ないようにする |
| トークンが複数プロセスで共有されるか | 全プロセスのSDK更新が終わるまで新形式の発行を有効化しない |
| トークンを「現在位置の唯一の証拠」として扱っているか | 最終処理ID、タイムスタンプ、チェックポイントログも併用する |
| 重複時に外部出力が二重登録されるか | UPSERT、ユニーク制約、冪等キーで防ぐ |
保存済みトークンがない場合
アプリケーション内でページングを完了し、トークンを永続化していない場合は、影響は比較的小さくなります。ただし、パーティション分割時の再試行やページング処理の安定性には関係するため、SDK更新後にページングの統合テストを行う価値はあります。
AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PKの確認ポイント
もう一つの変更は、query_items(partition_key=...)の内部継続トークン処理です。PR概要では、full partition key指定のクエリがfeed range側と同じ内部継続フレームワークを通るようになる一方、構造化トークンの発行は環境変数で制御されると説明されています。対象の環境変数はAZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PKです。(GitHub)
| 設定 | 挙動 |
|---|---|
| 未設定 | full-PKではレガシー形式の継続トークンを発行する。読み取りは両形式をサポートする |
1、true、yes、on | full-PKで構造化継続トークンを発行する。読み取りは両形式をサポートする |
| クライアント生成後に変更 | 既存のCosmosClientConnectionの挙動は変わらない |
この環境変数は「full-PKのみ」が対象であり、PR概要ではfeed-range、prefix-PK、cross-partition aggregator、change-feedは対象外と説明されています。つまり、設定を有効にしたからといって、すべてのCosmos DBクエリのトークンが一律に新形式へ切り替わるわけではありません。(GitHub)
実務では、次の順序で進めるのが安全です。
| 手順 | 作業 | 理由 |
| -: | ————————— | ————————– |
| 1 | まず新SDKを全Pod・全プロセスへ展開する | 読み取り側の互換性をそろえるため |
| 2 | 環境変数は未設定のまま動作確認する | レガシー形式の発行を維持し、混在リスクを下げるため |
| 3 | 保存済みトークンの利用状況を確認する | 古いプロセスが新形式トークンを受け取る事故を防ぐため |
| 4 | 全プロセス更新後に環境変数を有効化する | PR概要のロールアウト方針に沿うため |
| 5 | 有効化後はクライアントを再作成またはプロセス再起動する | 環境変数は接続構築時に読まれるため |
Kubernetesで運用している場合は、Deployment、CronJob、Job、サイドカー、手動実行用の管理コンテナまで確認してください。アプリ本体だけ新SDKでも、古いバッチワーカーが同じcontinuation tokenを読む設計なら、混在リスクは残ります。
移行前に確認するコマンドとコード
まず、現在利用しているazure-cosmosのバージョンを確認します。
python -m pip show azure-cosmos
python -m pip freeze | grep azure-cosmos
アプリケーション内でバージョンと環境変数をログに出す場合は、起動時に次のような確認を入れておくと、Podごとの設定差分を見つけやすくなります。
import os
import importlib.metadata
cosmos_version = importlib.metadata.version("azure-cosmos")
emit_structured_pk = os.environ.get("AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK")
print({
"azure_cosmos_version": cosmos_version,
"AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK": emit_structured_pk,
})
次に、コードベースから対象箇所を洗い出します。
grep -R "query_items" .
grep -R "feed_range" .
grep -R "partition_key" .
grep -R "continuation" .
単にquery_items()を使っているだけなら影響は限定的です。優先して確認すべきなのは、feed_range、continuation、by_page()、外部ストアへのトークン保存が組み合わさっている箇所です。
テストで見るべき観点
SDK更新後のテストでは、「エラーが出ない」だけでは不十分です。今回の変更はページングと再開に関わるため、結果件数、重複、再試行、トークン保存まで確認します。
| テスト観点 | 具体的な確認内容 |
|---|---|
| 全ページ取得 | 最後のページまで進めたとき、期待する総件数に近い結果が得られるか |
| 重複耐性 | 同じcontinuation tokenで再開しても外部出力が二重登録されないか |
| 途中失敗からの再開 | 1ページ取得後にプロセスを停止し、保存済みトークンから再開できるか |
| SDK混在 | 旧SDKプロセスが残っていない状態で新形式発行を有効にしているか |
| 空ページ | 空ページが返っても「完了」と誤判定していないか |
max_item_count | 指定値を「必ず返る件数」として扱っていないか |
Cosmos DBの公式ドキュメントでも、ページごとの件数は条件により変わり、空ページが返る場合もあると説明されています。したがって、アプリ側では「空ページだったから終了」ではなく、継続トークンやイテレーターの状態に基づいて終了判定する実装が安全です。(Microsoft Learn)
feed rangeを直接解析しない
feed_rangeを扱うコードでは、feed rangeの辞書構造をアプリケーション側で直接解釈しないことも重要です。Microsoft Learnでは、feed rangeのdict表現はキー構造が変わる可能性があり、opaque valueとして扱うべきだと注意されています。read_feed_ranges()についても、feed rangeはフィード操作の並列化に利用できる値として説明されています。(Microsoft Learn)
避けるべき実装例は、次のようなものです。
# 避けたい例: feed_rangeの内部キーを前提に分岐する
if feed_range["min"] < some_value:
...
安全なのは、SDKが返したfeed rangeをそのままquery_items(feed_range=...)へ渡し、内部構造に依存しないことです。今回のように継続トークンや範囲処理の内部実装が変わる場合、SDK外部で内部形式を前提にしたコードほど壊れやすくなります。
PRの状態も確認してから本番反映する
注意したいのは、指定されたPR #46506自体は2026年5月5日に「duplicate PR」としてクローズされている点です。関連する新しいPR #46692では、hotfixブランチ向けに同様のfeed range query fixが扱われており、2026年5月5日にもレビューや修正コメントが続いています。(GitHub)
そのため、本番反映前には次の3点を必ず確認してください。
| 確認先 | 見るべき内容 |
|---|---|
azure-cosmosのCHANGELOG | 対象修正がどのバージョンに入ったか |
| PyPIまたは社内ミラー | そのバージョンが取得可能か |
| GitHub PR・release notes | PRがマージ済みか、後続PRに置き換わっていないか |
今回の情報を「すでに全環境で適用済みの仕様」と断定するのではなく、「該当修正が含まれるSDKバージョンへ移行する際の確認事項」として扱うのが安全です。
まず取るべき行動
今回のAzure SDK documentation update: feed range query fixで、最初に行うべきことはコード変更ではなく棚卸しです。
query_items(feed_range=...)を使っている箇所、continuation tokenを保存している箇所、partition_key指定クエリでページングしている箇所を洗い出してください。次に、全プロセスのazure-cosmosバージョンをそろえ、環境変数AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PKを不用意に有効化していないか確認します。
特に、バッチ処理やワーカーでCosmos DBの大量データをページング取得している場合は、重複処理を前提にした冪等設計が重要です。保存済みトークンからの再開、パーティション分割後のリトライ、SDK更新時のバージョン混在は、運用中に見落とされやすいポイントです。
公開APIの変更がない更新ほど、アプリケーション側では「何もしなくてよい」と判断しがちです。しかし今回のように継続トークンとページングの内部挙動に関わる修正では、コードの見た目よりも、トークンの保存場所、再開ロジック、デプロイ順序を確認することが障害予防につながります。

コメント