0

I have a nested dictionary in my redis store and need to find all records where key_2 == "" then return value in key_3. All key_3 values will then be used to run mysql query to get key_2 value and update the redis store.

[
  ...
  task_44903: {"key_1": 44903, "key_2": "", "key_3": 1}
  task_44229: {"key_1": 44229, "key_2": 4, "key_3": 2}
  ...
]

My current way of achieving this is

    keys = r.keys(pattern='task_*')
    key_3 = set()
    for key in keys:
        values = r.get(key).decode('utf-8')
        values = ast.literal_eval(values)
        if values['key_2'] == '':
            key_3.add(values['key_3'])   

Is there a more concise way of achieving this?

1
  • 1
    Did you consider using RedisJSON.io and move it to the Redis side? Commented Sep 3, 2019 at 5:54

2 Answers 2

1

I'm not sure if this is what you wanted.

data = [
  {'task_44903': {"key_1": 44903, "key_2": "", "key_3": 1}},
  {'task_44229': {"key_1": 44229, "key_2": "", "key_3": 1}},
  {'task_44230': {"key_1": 44229, "key_2": "", "key_3": 2}}
]

set([ v['key_3'] for item in data for _, v in item.items()  if v['key_2']==""])

Output

{1, 2}
Sign up to request clarification or add additional context in comments.

Comments

0

Modify this to fit with your pipeline.

from itertools import chain


tasks = [
  {'task_44903': {"key_1": 44903, "key_2": "", "key_3": 1}},
  {'task_44229': {"key_1": 44229, "key_2": 4, "key_3": 2}}
]


def check_empty_key(tasks):
    # Your desired return value
    key_3s = set()

    # Makes a list of [{key_1:..., key_2:...}, {key_1:..., key_2:...}]
    task_details = chain.from_iterable(task.values() for task in tasks)
    # Iterate through each of these dictionaries
    for task_detail in task_details:
        # Will evaluate to True if task_detail['key_2'] is an empty string
        if not task_detail['key_2']:
            # Adds to the key_3s set
            key_3s.add(task_detail['key_3'])
            break
    else:
        # If no break statement was hit in the for loop, then raise this error
        raise ValueError('No empty key_2 in tasks')
    return key_3s

You could also do it like this:

def check_empty_key(tasks):
    key_3s = set()
    task_details = chain.from_iterable(task.values() for task in tasks)
    for task_detail in task_details:
        if not task_detail['key_2']:
            key_3s.add(task_detail['key_3'])
    return key_3s

But I like having the else so that I can raise an error when I need to add that into my control flow.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.