I am trying to do a query and sort by a bitwise value in an attribute that is a json object.
I want to sort based on whether a bit is set on an attribute.
Here is my class from my sqlalchemy model
The json in config attribute of the Disk model would be something like:
{ 'support': 876398789,
'size': 256,
'external': true,
'type': 'NAT' }
I would like to sort on whether a bit is set or not in the support field.
Below is my model:
class Disk(Base):
tablename = 'disks'
table_args = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_bin'}
id = Column(INTEGER(11), primary_key=True)
serial = Column(VARCHAR(255))
config = Column(TEXT)
@hybrid_property
def bitmap(self):
value = 0 # not configured
if self.config:
value = 1
if config_json.get('support', 0) & 0x8000 > 0: # check ACTIVE bit
value = 2
return value
@bitmap.expression
def bitmap(cls):
return case(
[
(func.json_extract(cls.config, '$.support').op('&')(0x8000)) > 0,
2],
else_=1
)
This works: disks = session.query(models.Disk).all()
It returns the disks with a bitmap value that has the value I would like.
But if I do a query: disks = session.query(models.Disk).order_by(desc(models.Disk.bitmap)).all()
When I do an order_by on the bitmap property I get the error:
NotImplementedError: Operator 'getitem' is not supported on this expression
I tried to use many versions of func.json_extract, or other case statements to no avail. This was my last attempt before realizing I might need to ask for help.
Is there a way to do an order_by on a json extracted bitmask, checking that the bit is checked or not?