Home > database >  pyjq - how to use "select" with both query and value as variables
pyjq - how to use "select" with both query and value as variables

Time:10-03

I am writing a code in python3 where i am struggling with usage of variables with "pyjq", the code works without variables but variables are not getting parsed inside pyjq.

The documentation referred is https://github.com/doloopwhile/pyjq/blob/master/README.md#api

Please check the code given below and suggest -

My code

import json, os
import pyjq
from flask import Flask, request, jsonify

def query_records():
    args = {"metadata.monitoring.enabled": "true"}
    for key, value in args.items():
      with open('/tmp/data.txt', 'r') as f:
          print (key)
          print (value)
          data = f.read()
          records = json.loads(data)
          query = ("."   key)
          print (query)
#jq '.[]|select(.metadata.monitoring.enabled=="true")' filename.json works,issue with variable substitution in python
          match = pyjq.all('.[]|select(["$query"]==$value)', records, vars={"value": value,"query": query})
          print (match)
query_records()

Content of file "/tmp/data.txt"

[
  {
    "name": "datacenter-2",
    "metadata": {
      "monitoring": {
        "enabled": "true"
      },
      "limits": {
        "cpu": {
          "enabled": "true",
          "value": "250m"
        }
      }
    }
  },
  {
    "metadata": {
      "allergens": {
        "eggs": "true",
        "nuts": "false",
        "seafood": "false"
      },
      "calories": 230,
      "carbohydrates": {
        "dietary-fiber": "4g",
        "sugars": "1g"
      },
      "fats": {
        "saturated-fat": "0g",
        "trans-fat": "1g"
      }
    },
    "name": "sandwich-nutrition"
  },
  {
    "metadata": {
      "allergens": {
        "eggs": "true",
        "nuts": "false",
        "seafood": "true"
      },
      "calories": 440,
      "carbohydrates": {
        "dietary-fiber": "4g",
        "sugars": "2g"
      },
      "fats": {
        "saturated-fat": "0g",
        "trans-fat": "1g"
      }
    },
    "name": "burger-nutrition"
  }
]

Expected output(which works without variables)

{
  "name": "datacenter-2",
  "metadata": {
    "monitoring": {
      "enabled": "true"
    },
    "limits": {
      "cpu": {
        "enabled": "true",
        "value": "250m"
      }
    }
  }
}

Current output []

seems like some issue with variables not being passed in case of "query" , help would be appreciated.

Edit 1 It works if I hardcode "query" - match = pyjq.all('.[]|select(.metadata.monitoring.enabled==$value)', records, vars={"value": value,"query": query})

but not vice-versa

which probably narrows it down to issue with the variable "query"

JQ is not a necessity and I can use other libraries too,given that json is returned

CodePudding user response:

Variables are intended to be used for values, not for jq expressions (at least not directly).

I think the easiest option here is to go for an fstring:

match = pyjq.all(f'.[]|select({query}==$value)', records, vars={"value": value})

and it probably makes sense to prepend the period inside the fstring:

match = pyjq.all(f'.[]|select(.{key}==$value)', records, vars={"value": value})
  • Related