0

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?

  • If anyone ever sees this post and wants to know what I did to solve this problem, I ended up having to extract the bit value into another field to allow the sorting. – Roger Desroches Jul 10 '23 at 15:49

0 Answers0