Files
hunjing/backend/app/models/idempotency.py
2026-08-21 16:00:13 +08:00

38 lines
1.7 KiB
Python

"""幂等键模型。"""
from datetime import datetime
from sqlalchemy import DateTime, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column
from app.core.ids import new_id
from app.core.time import utc_now
from app.db.base import Base
def new_idempotency_id() -> str:
return new_id("idempotency_")
class IdempotencyKey(Base):
__tablename__ = "idempotency_keys"
__table_args__ = (UniqueConstraint("scope", "key", name="uq_idempotency_scope_key"),)
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_idempotency_id)
key: Mapped[str] = mapped_column(String(200), nullable=False, index=True)
scope: Mapped[str] = mapped_column(String(120), nullable=False, index=True)
method: Mapped[str] = mapped_column(String(20), nullable=False)
path: Mapped[str] = mapped_column(String(500), nullable=False)
request_hash: Mapped[str] = mapped_column(String(128), nullable=False)
status: Mapped[str] = mapped_column(String(40), nullable=False, default="completed")
response_status_code: Mapped[int] = mapped_column(default=200)
response_body_json: Mapped[str] = mapped_column(Text, nullable=False)
resource_type: Mapped[str | None] = mapped_column(String(80))
resource_id: Mapped[str | None] = mapped_column(String(120))
trace_id: Mapped[str | None] = mapped_column(String(80), index=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), index=True)