您可以使用唯一约束来防止 2 列同时处于活动状态,但您必须使用 True 和 None 作为可能的值,而不是 True 和 False。这是因为唯一约束在列中只允许一个 True,但也只允许一个 False。 None(或 SQL NULL)值不参与唯一约束,因此您可以拥有与剩余行一样多的这些。为了确保数据库的完整性,最好使用只有一个可能值的枚举数据类型来实现。
import enum
class Active(enum.Enum):
true = True
class Credentials(db.Model):
active = db.Column(db.Enum(Active), unique=True)
您现在可以使用 Active.true 作为值来指示活动凭据,而 None 用于在数据库级别强制执行完整性的所有其他凭据。如果您打算让每个用户拥有一个活动凭据,而不是总共拥有一个活动凭据,则可以使用单独的 UniqueConstraint 语句来实现。
class Credential(db.Model):
__tablename__ = "credentials"
__table_args__ = (db.UniqueConstraint('user_id', 'active'),)
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
user = db.relationship("User", back_populates="credentials")
active = db.Column(db.Enum(Active))
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
credentials = db.relationship("Credential", back_populates="user")
虽然这确实可以防止多个凭据被标记为活动,但它不会阻止用户没有活动凭据,您需要依赖您的应用程序逻辑来实现这一点。