Python 是否可以将布尔列设置为Alchemy中的唯一约束?

Python 是否可以将布尔列设置为Alchemy中的唯一约束?,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,是否可以设置一个表,以便在任何给定时间只能将一条记录设置为true 我有一个“用户”表和一个“凭证”表。用户可以有一个或多个与其关联的登录凭据。一次只能有一个由凭证表中的“活动”列(布尔值)指示的“活动”凭证 是否可以设置某种约束以防止两条记录同时处于“活动”状态?因此,如果我阅读正确,您有两个模型类User和Credential,这是一对多关系: class User(db.Model): ... credentials = db.relationship('Credentia

是否可以设置一个表,以便在任何给定时间只能将一条记录设置为true

我有一个“用户”表和一个“凭证”表。用户可以有一个或多个与其关联的登录凭据。一次只能有一个由凭证表中的“活动”列(布尔值)指示的“活动”凭证


是否可以设置某种约束以防止两条记录同时处于“活动”状态?

因此,如果我阅读正确,您有两个模型类
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')
是否可以添加额外的foreignkey来表示一对一的关系:

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
在这里使用外键可以保持数据库的完整性


您需要一些额外的约束,即只能从用户由用户id定义的凭据列表中选择活动的\u凭据\u id。我在最后想到了这一点,如果我有解决方案,将在稍后更新答案。

您可以使用唯一约束来防止两列同时处于活动状态,但您将必须使用True和None作为可能的值,而不是True和False。这是因为unique约束只允许列中有一个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")

虽然这会阻止多个凭据被标记为活动凭据,但不会阻止用户没有活动凭据,因此您需要依赖您的应用程序逻辑来完成此操作。

如果您使用的是Postgresql,则是: