是否可以通过设置表的方式在任何给定时间将一个记录设置为true?
我有一个“用户”表和一个“凭据”表。用户可以具有一个或多个与其关联的登录凭据。凭据表中“活动”列(布尔值)指示的一次只能有一个“活动”凭据。
是否可以设置某种约束来防止两个记录同时处于“活动状态”?
答案 0 :(得分:0)
因此,如果我正确阅读,则有两个模型类User
和Credential
,这是一对多关系:
class User(db.Model):
...
credentials = db.relationship('Credential')
class Credential(db.Model):
...
user_id = db.Column(db.Integer, db.ForeignKey('user.id', nullable=False)
是否可以添加其他外键来表示一对一关系:
class User(db.Model):
...
active_credential_id = db.Column(db.Integer, db.ForeignKey('credential.id'))
class Credential(db.Model):
...
active_user = db.relationship('User')
您可以通过以下方式更新它:
inactive_credential = # some credential from the user's list of credentials
user = User.query.filter(User.id == inactive_credential.user_id)
user.active_credential_id = inactive_credential.id
db.session.add(user)
db.session.commit()
# inactive_credential ==>> active_credential
此处使用外键可维护数据库的完整性。
您将需要一些附加约束,说一个active_credential_id只能从其用户由user_id定义的凭据列表中选择。我只是在最后想到了这一点,如果有解决办法,稍后会更新答案。
答案 1 :(得分:0)
您可以使用唯一约束来防止同时激活2列,但是必须使用True和None作为可能的值,而不是True和False。这是因为唯一约束将仅在列中允许单个True,但也仅允许单个False。没有一个值(或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")
虽然这样做确实可以防止将多个凭证标记为活动凭证,但这不会阻止用户没有活动凭证,因此您需要依赖于应用程序逻辑。