Python 3.14のuuid7で時系列IDを作る方法|時刻取得とuuid4との違い

UUIDv7の先頭にあるUnixミリ秒の時刻領域と、後半のカウンター・乱数領域を分けて示す説明図
目次

結論:Python 3.14なら標準のuuid7を使える

Python 3.14以降では、標準ライブラリのuuid.uuid7()でUUIDv7を生成できます。UUIDv7は時刻由来の情報を先頭側に持つため、ランダム型のUUIDv4よりも生成順に近い並びを作りやすいIDです。ただし、IDだけで正確な業務日時や分散システム全体の発生順を証明できるわけではありません。

Python 3.14のuuid公式文書では、uuid7()は3.14で追加され、48ビットのタイムスタンプと42ビットのカウンターを使って、同一ミリ秒内の単調性を確保すると説明されています。一方、RFC 9562のUUIDv7仕様は、先頭48ビットをUnixエポックからのミリ秒と定め、残りを乱数や任意のカウンターなどに使える構造です。RFCの形式とCPythonの実装説明は分けて理解しましょう。

Pythonの実行版確認、UUIDv7生成、version確認、UTC日時変換、並び順の限界点検という5段階
UUIDv7を生成して時刻を読み、利用範囲を判断するまでの5段階を示す図解です。 · 図を拡大

最初に実行中のPythonとuuidの場所を確認する

AttributeError: module 'uuid' has no attribute 'uuid7'が出たときは、外部パッケージを追加する前に、実際に起動しているPythonの版と、読み込まれたuuidの場所を確認します。Python 3.13以前には標準のuuid.uuid7()がありません。また、プロジェクト内のuuid.pyなどが標準モジュールを隠している可能性もあります。

import sys
import uuid
from datetime import datetime, timezone

print("Python:", sys.version)
print("uuid module:", uuid.__file__)

if not hasattr(uuid, "uuid7"):
    raise RuntimeError("uuid.uuid7() is unavailable; check Python and uuid.__file__")

u = uuid.uuid7()

print("UUID:", u)
print("version:", u.version)
print("Unix ms:", u.time)
print(
    "UTC:",
    datetime.fromtimestamp(
        u.time / 1000,
        tz=timezone.utc,
    ),
)

生成された文字列や日時は実行ごとに変わります。確認点は、u.versionが7であること、u.timeがUnix時刻のミリ秒として取得できることです。秒を受け取るdatetime.fromtimestamp()には1000で割って渡し、timezone.utcを明示するとローカル時刻との混同を避けられます。

uuid4との違い

項目uuid4uuid7
主な構成ランダム値Unixミリ秒と実装依存の乱数・カウンター
生成APIuuid.uuid4()uuid.uuid7()
時刻の読み方.timeを作成時刻として読まないu.timeをUnixミリ秒として読める
並びの特徴生成順とは無関係同じ実装・条件では生成順に近い並びを得やすい

UUIDv4は公式文書でもランダムUUIDとして説明されています。UUIDオブジェクトにtime属性が見えても、v4の作成時刻を表すものではありません。版数を確認せず、すべてのUUIDの.timeを日時として扱わないことが重要です。

5個を逐次生成して並びを点検する

import uuid

ids = [uuid.uuid7() for _ in range(5)]

for value in ids:
    print(value)

print("sorted in this sample:", ids == sorted(ids))

この比較は、現在のプロセスで作った5個がPythonのUUID比較順でも同じ順序かを見る小さな点検です。RFC 9562の並び替えに関する節は、UUIDv7を生バイトや文字列表現で並べやすい形式として設計しています。しかし、上の結果が真でも、複数プロセス、複数ホスト、時計変更、異なる実装、データベースの型や照合規則まで含めた全順序を保証したことにはなりません。

業務日時と権限判定はIDから分離する

実務では、UUIDv7とは別にcreated_atを保存し、どの時計・タイムゾーン・精度を正とするかを決めてください。厳密な順序が必要なら、データベースの連番、トランザクション順、ログのオフセットなど、用途に合う列を別に持つ設計が安全です。

  • IDの時刻を、承認日時や受付日時などの正式記録の代わりにしない
  • UUIDを認証トークンや、値を知っているだけでアクセスできる権限キーにしない
  • UUIDv7の並びだけで、複数システム間の発生順を断定しない

RFC 9562のセキュリティ考慮事項も、UUIDを推測困難な権限情報とみなさないよう求めています。UUIDは識別子であり、認証・認可や改ざん検知を担う仕組みではありません。

文書の表示版と実行環境のパッチを混同しない

Python 3.14文書は現在3.14.8として表示され、Python 3.14.8の公式リリースページには2026年9月30日公開とあります。ただし、文書ヘッダーだけでは手元のPythonや個別変更の取り込み状況を判定できません。先ほどのsys.versionとuuid.__file__を基準に、必要なら固定リリースのソースや変更履歴まで確認します。別モジュールにある「unreleased」注記だけから、uuid7やPython 3.14.8全体を未公開・未搭載と判断しないでください。

また、CPythonのissue #138862では、UUIDv7のカウンターオーバーフロー後の時刻処理が議論されており、2026年10月13日時点ではOpenです。これはすべての通常生成が不正確だという意味ではありませんが、u.timeを絶対的な業務時刻と断定しない理由になります。実際の挙動は、利用中のPythonパッチ版と配布物で確認してください。

  1. sys.versionで実行版を確認する
  2. uuid.__file__で標準モジュールを読んでいるか確認する
  3. u.version == 7とUTC変換を確認する
  4. 業務日時と厳密な順序は別の列で保持する

この記事を書いた人

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

コメント

コメントする

目次