"""文章已读记录(per-user)。 设计: - 复合主键 (user_id, article_id) — 天然防重复,标记已读是幂等的 - read_at 默认 now(),用于排序(最近已读在前) - 索引: (user_id, read_at DESC) — 用户查自己最近已读用 (article_id) — 反向查"谁读过这文章"(暂不用,留扩展) 注意: - 删文章时 ondelete=CASCADE 自动清掉已读记录 - 这是和 bookmarks 并列的"用户行为"表 - user_id 是 Integer(users.id 是 Integer),article_id 是 BigInteger(articles.id 是 BigInteger) """ from __future__ import annotations from datetime import datetime from sqlalchemy import BigInteger, DateTime, ForeignKey, Index, Integer, func from sqlalchemy.orm import Mapped, mapped_column from app.database import Base class ArticleRead(Base): __tablename__ = "article_reads" user_id: Mapped[int] = mapped_column( Integer, ForeignKey("users.id", ondelete="CASCADE"), primary_key=True ) article_id: Mapped[int] = mapped_column( BigInteger, ForeignKey("articles.id", ondelete="CASCADE"), primary_key=True, ) read_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False, ) __table_args__ = ( Index("ix_article_reads_user_read_at", "user_id", "read_at"), Index("ix_article_reads_article", "article_id"), ) def __repr__(self) -> str: return f""