承認した2件は任意の2件ではない
一言でいうと
変更の承認は、何件変えてもよいという許可ではありません。どの顧客のどの行を、どんな状態からどんな状態に変えるかについての合意です。
なぜ必要なのか
祭りの運営者が、雨のため一部の軽食の注文をキャンセルしてほしいと依頼しました。朝に待機中の注文を2件照会し、承認を受けました。昼に実行しようとすると、1件は別の担当者が数量を変更しており、同じ顧客の新しい待機中の注文も入ってきていました。朝に使ったWHERE条件をもう一度実行すると、承認のときになかった注文までキャンセルしてしまうおそれがあります。SELECTが正しかったという事実と、あとのUPDATEが承認範囲を守るという事実は、同じではありません。
前のレッスンでは、広い依頼を絞り込み、バックアップと中止基準を用意しました。今回は、時間という変数を加えます。人が承認ドキュメントを読んでいる間も、データベースは動き続けます。読み取りから適用までテーブル全体をロックすると、その間の他の業務が止まります。そこで、承認時点の観測を小さな明示的データとして残し、実行時にその観測がまだ有効かを比較します。比較が失敗したら止めて新しい承認を得る必要があり、現在の値で黙って計画を変えてはいけません。
どう動くのか
このラボの承認対象は、id・revision・qtyの3つの値です。顧客を区別するtenantは、別の引数として渡します。たとえば、blue顧客の注文1がrevision=3、qty=7のときに承認を得たなら、適用条件にはこれらの値とpending状態がすべて入ります。IDだけだと、他の担当者が変えた値を上書きしてしまうおそれがあり、バージョンだけだと、他の顧客の行を変えてしまうおそれがあります。値を1つ検査する仕組みではなく、承認した事実全体を保存する契約です。
승인 때: 고객 blue / 주문 1 / 버전 3 / 수량 7 / pending
적용 때: 고객 blue / 주문 1 / 버전 4 / 수량 7 / pending
판단: 수량이 같아도 버전이 바뀌었으므로 재확인
バージョンは最後の数字ではなく、変更履歴を区別する目印です。数量が7から8に変わり、また7に戻った可能性があります。値を比較するだけでは、この往復を区別できません。今回の契約では、すべての正常な業務変更がrevisionを増やすという前提を置きます。他のプログラムがその規則なしにテーブルを変更すると、保護される範囲が変わるので、運用では書き込み経路と権限も一緒に管理する必要があります。このラボのトークン1つが、すべての書き込みプログラムを統制してくれるわけではありません。
承認セットは、IDで並べ替えたコピーとして作ります。同じ2つの対象を逆の順序で受け取ったからといって、別の変更と見なさないためです。逆に、同じIDが2回入ってきたら、1つの行を2回扱おうとする曖昧さが生じるので拒否します。空のリストも、成功として処理しません。件数が0の実行を受け入れると、入力を失ったバグが、何事もなく終わった正常な作業として記録されるおそれがあります。このレッスンでは、1個から16個までの小さなバッチを使います。
数値の検証も、単なる防御コードではありません。PythonではTrueがintのサブタイプなので、緩い検査では、注文ID 1のように通ってしまうことがあります。承認資料で論理値が番号に変わるのは、データ解釈のエラーです。id・revision・qtyに正確な整数の範囲を定め、boolを拒否します。返した計画を別のコードが変更しても、元の入力が一緒に変わらないように、各対象も新しいdictにコピーします。
現場での姿
顧客が最も多く尋ねるのは、SQLの文法よりも影響範囲です。なぜこの2件の注文だけを変更するのか、他の顧客にはなぜ影響がないのか、承認後に変わった件があれば誰が改めて判断するのかを、説明できなければなりません。したがって、変更ツールの入力は、担当者に見せた計画とつながっている必要があります。技術者が読んだCSVと実際に実行した一覧が食い違っていれば、承認手続きがあっても安全ではありません。
実際のFDEの業務は、顧客の課題を理解し、データとアプリケーションで解決し、デプロイまで責任を持つ仕事とつながっています。下のPalantirの公開求人票も、顧客との協業、アーキテクチャ、データ中心の実装を求めています。ただし、この求人票が特定のPostgreSQLの手法や今回の例のスキーマを求めているという意味ではありません。ここでは、その役割に必要な変更範囲の説明と実装の検証を、小さな架空の事例で練習します。実際の顧客データや個人情報は使いません。
計画を残すことと、権限を得ることも区別します。tenant文字列を関数に渡したからといって、呼び出し元がその顧客を変更する権限を得るわけではありません。この関数は、権限のある担当者が呼び出すという前提のもとで、同時変更の衝突を検査します。本番APIでは、ログイン、顧客範囲の権限、承認主体、監査の保存ポリシーを、別に強制する必要があります。テスト用のDBアカウントを、実サービスの運用アカウントの例として使ってはいけません。
次の確認ですること
続くクイズで、同じ件数で異なるID、同じ値で異なるバージョン、重複IDと空の承認を区別します。あとの総合ラボでは、previewで観測した計画を、実際の2つのPostgreSQL接続の間で古くしたうえで、適用が拒否されるかを確認します。失敗した対象だけをこっそり新しい値に変更せず、変更の前提を改めて確認する練習です。
参考: Palantir FDSEの求人票、PostgreSQL UPDATE。求人票は2026-09-13に確認したもので、採用の保証や試験の出題範囲を意味するものではありません。