Reputation: 4634
How can I map multiple Boolean properties into single SQLAlchemy column?
I have a class kind of flags
:
class Thing(db.Model):
id = db.Column(db.Integer, primary_key=True)
isEnabled = db.Column(db.Boolean, nullable=False, default=False)
isAdministrator = db.Column(db.Boolean, nullable=False, default=False)
isPasswordExpired = db.Column(db.Boolean, nullable=False, default=False)
isEmailConfirmed = db.Column(db.Boolean, nullable=False, default=False)
isPhoneConfirmed = db.Column(db.Boolean, nullable=False, default=False)
# ... many more booleans #
I'd like to store them into single db.Column(db.Integer)
or something like that small field.
Could you help me with example of how should I do this?
Please don't try to get logic of those fields or help me to store password expiration mark better - this is an example.
Upvotes: 0
Views: 256
Reputation: 5264
You can use an enum.IntFlag
to store all those flags in a single Integer
field.
from sqlalchemy import Column, Integer, create_engine
from sqlalchemy.orm import declarative_base, Session
from enum import IntFlag, auto
class UserFlag(IntFlag):
ENABLED = auto()
ADMINISTRATOR = auto()
PASSWORD_EXPIRED = auto()
EMAIL_CONFIRMED = auto()
PHONE_CONFIRMED = auto()
Base = declarative_base()
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
user_flags = Column(Integer, nullable=False)
engine = create_engine("sqlite://", future=True, echo=True)
Base.metadata.create_all(engine)
session = Session(bind=engine)
admin = User(user_flags = UserFlag.ENABLED | UserFlag.ADMINISTRATOR)
ljmc = User(user_flags = UserFlag.ENABLED | UserFlag.PASSWORD_EXPIRED)
session.add(admin)
session.add(ljmc)
session.commit()
bool(admin.user_flags & UserFlag.ADMINISTRATOR) # True
bool(ljmc.user_flags & UserFlag.ADMINISTRATOR) # False
You can also set a helper method to check the flags:
def is_user_flag_set(self, flag: UserFlag) -> bool:
return self.user_flags & flag != 0
usage
admin.is_user_flag_set(UserFlag.ADMINISTRATOR) # True
Upvotes: 1