如何将多个布尔属性映射到单个SQLAlchemy二进制/整数列?
实现示例
可以用位掩码的方式把多个布尔值打包到单个Integer字段里,下面是修改后的Thing类实现:
class Thing(db.Model): id = db.Column(db.Integer, primary_key=True) # 用单个整数字段存储所有标志位 flags = db.Column(db.Integer, nullable=False, default=0) # 定义每个布尔属性对应的位掩码 _ENABLED_FLAG = 1 << 0 # 对应二进制 00001 _ADMIN_FLAG = 1 << 1 # 对应二进制 00010 _PWD_EXPIRED_FLAG = 1 << 2 # 对应二进制 00100 _EMAIL_CONFIRMED_FLAG = 1 << 3 # 对应二进制 01000 _PHONE_CONFIRMED_FLAG = 1 << 4 # 对应二进制 10000 # isEnabled 属性的 getter 和 setter @property def isEnabled(self): return (self.flags & self._ENABLED_FLAG) != 0 @isEnabled.setter def isEnabled(self, value): if value: self.flags |= self._ENABLED_FLAG else: self.flags &= ~self._ENABLED_FLAG # isAdministrator 属性 @property def isAdministrator(self): return (self.flags & self._ADMIN_FLAG) != 0 @isAdministrator.setter def isAdministrator(self, value): if value: self.flags |= self._ADMIN_FLAG else: self.flags &= ~self._ADMIN_FLAG # isPasswordExpired 属性 @property def isPasswordExpired(self): return (self.flags & self._PWD_EXPIRED_FLAG) != 0 @isPasswordExpired.setter def isPasswordExpired(self, value): if value: self.flags |= self._PWD_EXPIRED_FLAG else: self.flags &= ~self._PWD_EXPIRED_FLAG # isEmailConfirmed 属性 @property def isEmailConfirmed(self): return (self.flags & self._EMAIL_CONFIRMED_FLAG) != 0 @isEmailConfirmed.setter def isEmailConfirmed(self, value): if value: self.flags |= self._EMAIL_CONFIRMED_FLAG else: self.flags &= ~self._EMAIL_CONFIRMED_FLAG # isPhoneConfirmed 属性 @property def isPhoneConfirmed(self): return (self.flags & self._PHONE_CONFIRMED_FLAG) != 0 @isPhoneConfirmed.setter def isPhoneConfirmed(self, value): if value: self.flags |= self._PHONE_CONFIRMED_FLAG else: self.flags &= ~self._PHONE_CONFIRMED_FLAG
用法说明
使用方式和原来的布尔属性完全一致:
# 创建实例并设置属性 thing = Thing() thing.isEnabled = True thing.isAdministrator = False db.session.add(thing) db.session.commit() # 读取属性 print(thing.isEnabled) # 输出 True print(thing.isAdministrator) # 输出 False
每个布尔属性对应整数中的一个二进制位,设置属性时通过位运算修改flags字段的值,读取时通过位运算判断对应位是否为1。如果需要添加更多布尔属性,只需要定义新的位掩码(比如_NEW_FLAG = 1 << 5),再实现对应的property即可。
内容的提问来源于stack exchange,提问作者filimonic
相关产品推荐
相关产品推荐

