SQLAlchemy - 如何使每个 ForeignKey 关系的列唯一?

SQLAlchemy - how to make column unique per ForeignKey relationship?

在下面的 Todo 模型中,text 列有一个唯一约束。

如何缩小此约束以仅验证每个“外键”用户的唯一性,而不是像现在这样每个用户?

我使用 SQLite。

from sqlalchemy import Column, Integer, String, Boolean, ForeignKey
from sqlalchemy.orm import relationship

from database import Base

class Todo(Base):
    __tablename__ = 'todos'
    id = Column(Integer, primary_key=True, index=True)
    text = Column(String, unique=True)
    user_id = Column(Integer, ForeignKey('users.id'))

    user = relationship("User", back_populates="todos")

class User(Base):
    __tablename__  = 'users'
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String, unique=True, index=True)
    hashed_password = Column(String)
    is_active = Column(Boolean, default=True)

    todos = relationship("Todo", back_populates="user")

如果你使用postgresql,你可以使用Partial Index来实现这个:

class Todo(Base):
    __tablename__ = 'todos'
    id = Column(Integer, primary_key=True, index=True)
    text = Column(String)  # ! removed the unique from here
    user_id = Column(Integer, ForeignKey('users.id'))

    user = relationship("User", back_populates="todos")

    # ! added unique index with 
    __table_args__ = (
        Index(
            "todo_text_uc",
            "text",
            unique=True,
            postgresql_where=(user_id != None),
            # postgresql_where=(~user_id.is_(None)),  # equivalent to the row above, but no linting warnings
        ),
    )

For sqlite just replace postgresql_where with sqlite_where.