Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Analytics runner - iterate over keys the Python 3 way #4538

Merged
merged 2 commits into from
Jan 13, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion redash/query_runner/google_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def run_query(self, query, user):
params = json_loads(query)
except:
params = parse_qs(urlparse(query).query, keep_blank_values=True)
for key in params.keys():
for key in [*params]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is the issue:

>>> d = {'ab': 'yesterday', 'cd': 2}
>>> for k in d.keys():
...     print(k)
... 
ab
cd

(this shows that the keys are iterated properly)

But, check the following:

>>> ",".join("yesterday")
'y,e,s,t,e,r,d,a,y'

So the issue is actually line 168 which applies ",".join on any value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The real problem is line 170, which messes around with the dict_keys iterator, something that didn't happen in Python 2. Populating a new list of keys with [*params] solves this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for key in [*params]:
# Because we change keys list on line 170, we need to create a copy of the keys
for key in [*params]:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option that would make fiddling with iterators (and the need to explain it) redundant is:

 query_string = parse_qs(urlparse(query).query, keep_blank_values=True) 
 params = {k.replace('-', '_'): ",".join(v) for k,v in query_string.items() }

We'll still have to explain ",".join, but maybe we don't have to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this 👍

params[key] = ",".join(params[key])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
params[key] = ",".join(params[key])
# parse_qs returns every value as a list
params[key] = ",".join(params[key])

if "-" in key:
params[key.replace("-", "_")] = params.pop(key)
Expand Down