Azure SDKのfeed range query修正バックポートとは?Cosmos DB Python SDKの確認ポイント

2026年5月4日公開・更新分として確認された「Azure SDK documentation update: feed range query fix backported」は、Azure SDKのうち Azure Cosmos DB Python SDK(azure-cosmos) を使っている開発者が確認すべき更新です。

結論から言うと、公開APIの変更はありません。ただし、query_items(feed_range=...) でページングしている処理や、query_items(partition_key=...) の継続トークンを保存・再利用している処理では、SDK更新後の挙動確認が必要です。特に、パーティション分割後に古い feed_range を使い続けるバッチ、ワーカー、データ再処理ジョブでは、重複読み取りや再処理を前提にした設計になっているかを見直してください。PRでは、2つの継続トークン関連変更を同一リリースに含め、公開APIは変更しないと説明されています。(GitHub)

目次

今回のAzure SDK更新で何が変わったのか

今回の更新は、Azure Cosmos DB Python SDKのクエリページング、特に継続トークンの扱いを改善するものです。主な変更点は次の2つです。

変更点対象実務上の意味
query_items(feed_range=...) のページング修正feed rangeを指定したクエリパーティション分割後に、複数の物理パーティション範囲へまたがるケースで、ページングの正確性と復元性を改善
query_items(partition_key=...) の内部トークン経路統一フルパーティションキー指定クエリ公開APIは変えず、内部的に継続トークン処理を統一。構造化トークンの出力は環境変数で段階的に有効化

重要なのは、「コードの呼び出し方が変わる更新」ではなく、「同じコードでも、継続トークンの保存・復元・再開の安全性に関わる更新」だという点です。

PRのCHANGELOGでは、query_items(feed_range=...) において、指定されたfeed rangeがパーティション分割により複数の物理パーティションに重なる場合、ページング結果が不正確になる可能性があるバグを修正したと記載されています。対象ブランチは hotfix/azure-cosmos_4.14.6 で、PR上のCHANGELOGでは 4.14.7 (Unreleased) のバグ修正として扱われています。(GitHub)

なぜfeed range queryの修正が重要なのか

Azure Cosmos DBでは、データ量やスループットの状況に応じて、物理パーティションが分割されることがあります。通常のアプリケーションコードでは意識しないことも多いですが、feed_range を使ってクエリ範囲を明示している場合、過去に取得したfeed rangeが、後から複数の物理パーティション範囲にまたがることがあります。

このとき問題になるのがページングです。

たとえば、次のような処理を考えます。

for page in container.query_items(
    query="SELECT * FROM c",
    feed_range=feed_range,
    max_item_count=100
).by_page():
    process(list(page))

この処理は一見すると「1ページ最大100件」と期待されます。しかし、古いfeed rangeが複数の物理パーティション範囲に重なった場合、内部ではそれぞれの範囲へ問い合わせが行われ、結果をマージします。過去の不具合では、このマージ後のページサイズや継続トークンの扱いが問題になり、期待と異なる件数、重複、欠落、終了しない反復などにつながる可能性が指摘されていました。関連Issueでは、feed_range が複数の物理PK範囲に重なる場合、最後の内部範囲の継続トークンだけを呼び出し元に返すと、次ページ取得時に重複・欠落・非終了のリスクがあると説明されています。(GitHub)

つまり、今回の修正は単なるドキュメント上の小さな変更ではありません。feed rangeを使って大量データを分割処理している環境では、データ処理の正確性に直結します。

影響を受けやすいシステム

今回のAzure SDK更新で特に確認すべきなのは、次のようなシステムです。

利用パターン影響度確認すべきこと
query_items(feed_range=...) を使ってページングしている高パーティション分割後も全件取得できるか、重複処理に耐えられるか
feed rangeやcontinuation tokenをDB・Redis・Queueなどに保存して再開している高SDK更新前後のトークン混在時に想定外の再読込が起きても安全か
複数Pod・複数VM・複数ワーカーで同じジョブを処理している高全プロセスが同じSDKバージョンへ更新される前に新形式トークンを出していないか
query_items(partition_key=...) の継続トークンを使っている中環境変数による構造化トークン出力をいつ有効化するか
feed rangeを使わず、通常の単発クエリだけを実行している低通常の回帰テストで十分な可能性が高い

特に注意したいのは、バッチ処理やETL処理です。Webアプリの単発検索よりも、長時間にわたってページングし、途中状態を保存し、失敗時に再開する処理のほうが影響を受けやすくなります。

公開APIは変わらないが、運用上の確認は必要

PRでは、公開APIの変更はないと説明されています。つまり、query_items() の呼び出し形式を変えたり、新しい引数を必ず追加したりする必要はありません。(GitHub)

ただし、公開APIが変わらないからといって、何も確認しなくてよいわけではありません。今回の変更は、継続トークンという「アプリケーションの外側に保存されることが多い状態」に関係します。

たとえば、次のような設計では注意が必要です。

1. クエリを1ページ処理する
2. continuation tokenをDBに保存する
3. 次回ジョブで保存済みtokenから再開する
4. 複数ワーカーが同じ処理を分担する

この場合、SDK更新前に保存されたトークンを、SDK更新後のプロセスが読む可能性があります。逆に、一部のプロセスだけが新しいSDKになり、新しい形式のトークンを古いSDKのプロセスが読む可能性もあります。

PRでは、feed rangeパスの古い不透明トークンは安全性を優先して「最初から開始」として扱う方針が示されており、その結果、以前の位置からの完全な再開ではなく、前の位置から再読込が起きる可能性があると説明されています。まれな移行中の再試行・再開パスでは、最大1件程度の重複行が起きる可能性にも触れています。(GitHub)

AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK の確認ポイント

今回の変更では、query_items(partition_key=...) のフルパーティションキー指定クエリについて、構造化継続トークンの出力を環境変数で制御します。

環境変数名は次のとおりです。

AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK

PRでは、この環境変数が未設定の場合は従来形式のフルPK継続トークンを出力し、読み取り側は従来形式と構造化形式の両方をサポートすると説明されています。有効値として 1、true、yes、on が示されており、有効化すると構造化されたフルPK継続トークンを出力します。なお、この設定値は CosmosClientConnection の構築時に読み込まれるため、環境変数を後から変更しても既存クライアントの挙動は変わりません。(GitHub)

設定出力されるトークン読み取り互換性推奨される使い方
未設定従来形式従来形式・構造化形式の両方を読み取り混在デプロイ中の安全な初期状態
1 / true / yes / on構造化形式従来形式・構造化形式の両方を読み取り全プロセスのSDK更新後に段階的に有効化
途中で環境変数だけ変更既存クライアントには反映されないクライアント再作成が必要Pod再起動、プロセス再起動、クライアント再生成を計画

ここで失敗しやすいのは、「環境変数を変えたから即座に挙動が変わる」と思い込むことです。実際にはクライアント接続構築時に読まれるため、KubernetesならPod再起動、常駐プロセスならプロセス再起動、アプリ内で長寿命のCosmosClientを持っているならクライアント再生成が必要です。

推奨されるロールアウト手順

PRのロールアウトガイダンスでは、まず新しいSDKを環境変数オフの状態で全体へ展開し、全Pod・全プロセスの更新を確認してから、構造化フルPKトークンの出力を有効化する流れが示されています。(GitHub)

実務では、次の順番で進めるのが安全です。

| 手順 | 作業 | 判断基準 |
| -: | ————————————————————————— | —————————— |
| 1 | 現在の azure-cosmos バージョンを棚卸しする | 本番、ステージング、バッチ、ワーカーで差がないか |
| 2 | query_items(feed_range=...) と query_items(partition_key=...) の利用箇所を洗い出す | continuation tokenを保存している箇所を優先 |
| 3 | 修正を含むSDKへステージングで更新する | 公式CHANGELOGやPyPIで実際の配布バージョンを確認 |
| 4 | 環境変数は未設定のまま全プロセスへ展開する | mixed-version状態で新形式トークンを出さない |
| 5 | ページング、再開、重複処理のテストを実行する | 件数、重複、欠落、終了条件を確認 |
| 6 | 全プロセス更新後に必要なら AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK=1 を有効化する | 旧SDKプロセスが残っていないことを確認 |
| 7 | 有効化後にCosmosClientを再作成またはプロセス再起動する | 設定がクライアント構築時に読まれるため |

Microsoft Learnでは、Azure Cosmos DB Python SDKのリリース履歴は azure-sdk-for-python リポジトリのCHANGELOGで管理されていると案内されています。また、新機能や最適化は現在のSDKに追加されるため、可能な限り最新バージョンへアップグレードすることが推奨されています。(Microsoft Learn)

バージョン確認と更新時のコマンド例

まず、本番・ステージング・CI・バッチ実行環境で、実際に使われている azure-cosmos のバージョンを確認します。

python -m pip show azure-cosmos

依存関係ファイルも確認します。

grep -n "azure-cosmos" requirements.txt pyproject.toml poetry.lock Pipfile.lock 2>/dev/null

更新する場合は、組織の運用方針に合わせて、明示的なバージョン固定を検討します。

python -m pip install --upgrade azure-cosmos

厳密に管理する環境では、公式CHANGELOGやPyPIで修正を含むバージョンを確認したうえで固定します。

python -m pip install "azure-cosmos==<修正を含む確認済みバージョン>"

注意点として、PR上では 4.14.7 (Unreleased) のCHANGELOG項目として記載されていますが、実際の配布状況は公開タイミングによって変わります。記事作成時点で何かのバージョン番号を機械的に指定するのではなく、自社環境では必ず公式のリリース履歴、PyPI、ロックファイルを突き合わせてください。PyPIの azure-cosmos ページでは、最新バージョン、リリース日、必要Pythonバージョンなどを確認できます。(PyPI)

テストで確認すべき観点

今回のAzure SDK更新では、単に「アプリが起動するか」だけでは不十分です。継続トークンを使ったページングの挙動を重点的に確認してください。

feed rangeを使っている場合

feed rangeを使う処理では、次の観点をテストします。

テスト項目確認内容
1ページの件数max_item_count を超える件数が返らないか
全件取得ページング完了後に期待件数と一致するか
再開処理途中で停止し、保存済みトークンから再開できるか
重複許容再読込が起きても二重登録・二重課金・二重通知にならないか
終了条件反復が終わらない状態にならないか
パーティション分割後古いfeed rangeを使った処理でも安全に完了するか

PR #46469では、query_items(feed_range=..., max_item_count=N) が複数の物理PK範囲に重なると、1ページに最大 K×N 件が返る可能性がある問題が説明されていました。その後、マージ結果をユーザー指定のページサイズに切り詰める修正と、切り詰め時に継続トークンを抑制する安全策が説明されています。(GitHub)

partition_key指定クエリを使っている場合

partition_key を指定したクエリでは、主に環境変数と混在デプロイを確認します。

# Linux / macOS
export AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK=1
# PowerShell
$env:AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK = "1"

ただし、本番でいきなり有効化するのは避けるべきです。まずは未設定のまま全プロセスを新SDKへ更新し、古いSDKが残っていないことを確認します。その後、ステージングで構造化トークン出力を有効化し、問題がなければ本番へ段階展開します。

重複読み取りに備えた実装にしておく

今回の更新に限らず、クラウドDBのページング処理では「同じデータをもう一度読む可能性」を完全には排除しにくいケースがあります。特に継続トークンを外部保存して再開するバッチでは、重複読み取りを前提にしておくと障害に強くなります。

実務で有効なのは、次のような実装です。

def process_item(item):
    # idや業務キーを使って冪等に処理する
    unique_key = item["id"]

    if already_processed(unique_key):
        return

    write_result(item)
    mark_as_processed(unique_key)

悪い例は、「ページングで返ってきた順番」と「処理済み件数」だけを信頼する設計です。

前回は1000件まで処理したので、次は1001件目から処理する

この考え方は、分割、再試行、再読込、並列処理がある環境では崩れやすくなります。Cosmos DBのアイテムID、業務上の一意キー、処理済みテーブルなどを使い、同じアイテムが再度渡されても結果が変わらないようにしておくべきです。

すぐ対応すべきかの判断基準

すべてのAzure SDK利用者が緊急対応すべき更新ではありません。優先度は、feed rangeと継続トークンの使い方で判断します。

判断基準対応優先度
feed_range を指定したクエリで大量データをページングしているすぐ確認
continuation tokenを永続化し、別プロセス・別タイミングで再開しているすぐ確認
Kubernetesやバッチ基盤で複数ワーカーが同じ処理を分担している早めに確認
partition_key 指定クエリのページングを使っている環境変数の扱いを確認
Cosmos DBを使っているが単発CRUD中心通常のSDK更新計画で対応
Azure SDKは使っているがCosmos DB Python SDKではない原則として今回の直接影響は小さい

特に、分析基盤、データ移行、監査ログ処理、再集計バッチ、イベント再処理のように「全件を正確に読む」ことが重要な処理では、ステージングで件数比較まで行うべきです。

移行時にやってはいけないこと

今回のような継続トークン関連の更新では、次の対応は避けてください。

NG対応なぜ危険か
一部のPodだけ新SDKにして、すぐ構造化トークン出力を有効化する古いSDKが新形式トークンを扱えない可能性がある
保存済みcontinuation tokenを無条件に信頼する旧形式トークンが再読込につながる可能性がある
件数確認なしで本番バッチへ適用する欠落や重複に気づきにくい
環境変数変更だけで反映済みと判断する設定はクライアント構築時に読まれる
重複処理を考慮せず、外部API呼び出しや課金処理を直結する再読込時に二重実行のリスクがある

今回の更新を確認するためのチェックリスト

本番適用前に、最低限次の項目を確認してください。

□ azure-cosmos の利用バージョンを全環境で確認した
□ query_items(feed_range=...) の利用箇所を洗い出した
□ query_items(partition_key=...) で continuation token を使う箇所を確認した
□ 保存済み continuation token の保管場所を把握した
□ SDK更新前後でページング件数の比較テストを行った
□ 再開処理で重複・欠落が起きても検知できるようにした
□ AZURE_COSMOS_EMIT_STRUCTURED_CONTINUATION_PK を有効化するタイミングを決めた
□ 全Pod・全プロセス更新後にだけ構造化トークン出力を有効化する方針にした
□ 環境変数変更後にCosmosClientの再作成またはプロセス再起動を行う手順を用意した

まとめ:API変更なしでも、継続トークン運用は必ず見直す

今回のAzure SDK documentation update: feed range query fix backportedは、Azure Cosmos DB Python SDKの query_items(feed_range=...) と継続トークン処理に関する重要な修正です。公開APIは変わらないため、通常のアプリコードはそのまま動く可能性が高い一方で、ページング、保存済みトークン、複数プロセス運用では確認が欠かせません。

対応の要点は3つです。

まず、feed_range を使っている処理を洗い出し、パーティション分割後でもページング結果が正しいかを確認します。次に、partition_key 指定クエリの構造化トークン出力は、全プロセスを新SDKへ更新してから段階的に有効化します。最後に、再読込や重複が起きても安全な冪等処理にしておきます。

次に取るべき行動は、azure-cosmos のバージョン確認と、query_items(feed_range=...) の利用箇所の棚卸しです。該当箇所がある場合は、SDK更新そのものよりも先に、ページング件数、再開処理、重複処理のテスト計画を作成してください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次