I have a dictionaries list and I want to apply a 'SQL like' filter query on it.
The user provides the string which can be something like this:
"type1==Hello && type2=~World" - AND operator
"type1==Hello || type2=~World" - OR operator
I managed to filter one argument for example "type1==Hello", without the && / ||.
Basically, I'm struggling to map the 'SQL like' format to a genuine filter on the dictionaries list using && || (and/or operators).
If someone can help me out, it will be great
def filter_host(hosts, filter_str, categories):
def not_contains(a, b):
return b not in a
def and_(a, b):
return a and b
def or_(a, b):
return a or b
ops = {
"==": operator.eq,
"<": operator.lt,
">": operator.gt,
"!=": operator.ne,
'=~': operator.contains,
'!~': not_contains,
'&&': and_,
'||': or_
}
try:
key, op, value = re.match(r'(\w+)\s*(>|<|(?<!=)~=(?!=)|(?<!=)==(?!=)|(?<!=)>(?!=)|(?<!=)!~(?!=)|(?<!=)!=(?!=))\s*(\w*.*|\d*.*)',
filter_str).groups()
if key in categories:
if _keys_mapping.get(key).get('type') == 'float':
value = float(value)
elif _keys_mapping.get(key).get('type') == 'int':
value = int(value)
operator_func = ops[op]
filtered_hosts = list(filter(lambda host: operator_func(host.get(_keys_mapping[key]['name']), value), hosts))
if filtered_hosts:
return filtered_hosts
else:
raise Exception('No matching values')
else:
raise Exception('Key not exist. Allowed keys for this query are: ' + ', '.join(categories))
except ValueError:
handle_exceptions('Filter option not implanted')
except AttributeError:
handle_exceptions('Filter option not implanted')