-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
Load custom encoder only when runner enabled #6748
Load custom encoder only when runner enabled #6748
Conversation
redash/utils/json.py
Outdated
"""Adapter for `json.dumps`.""" | ||
|
||
def __init__(self, **kwargs): | ||
self.encoders = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious why is this an array? Is it possible to have result from multiple query runners at this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not a result, these are custom json encoder functions for each query runner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is there control then on what custom_json_encoder is actually used? For example, pg.py and mognodb.py both have custom_json_encoder defined. Then self.encoders will be [encoder_from_pg, encoder_from_mongodb].
In that case, say we had a query result from mongo which needed to be encoded, wouldn't the following code try to use both encoders, one by one and say if both encoders had different logic for encoding Timestamp, whichever encoder is first in list get to do the encoding?
def default(self, o):
for encoder in self.encoders:
result = encoder(self, o)
if result:
return result
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't matter which encoder is first, cause custom encoders are to process custom data types, provided by runner's lib, like ObjectId for mongodb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed a fix for #6747
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't get how your change isn't recursive? if encoder(self, o) returned an encoded string, then none of the elif condition in default(...) catch it, which would result in super().default(o) called again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super().default(o) calls default method of json.JSONEncoder not redash.utils.json.JSONEncoder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for clarification : )
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #6748 +/- ##
==========================================
+ Coverage 63.41% 63.42% +0.01%
==========================================
Files 162 162
Lines 13169 13173 +4
Branches 1819 1819
==========================================
+ Hits 8351 8355 +4
Misses 4522 4522
Partials 296 296
|
this MR will fail cause it's now running against master, need to merge it to fix CI |
Hi Andrii, thanks for the PR. Obviously we'll need to fix CI first before considering this. That being said, this is the third json-encoder-related PR I've seen but I'm still unclear on what is going on with these changes and what the fix is, as well as how it's been tested. Would you mind spending some time explaining these changes more in depth? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(placeholder)
previous json related PR fixed custom JSON encoders dynamic loading, but it didn't take into account if a runner is enabled, that's why tests in master are failing, cause it doesn't install mongodb dependencies before running cypress tests. I've ran cypress tests locally to validate for and instance with and without mongo dependencies |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, please don't put unrelated changes into a PR like this, it makes it hard to track what happens in a PR. Future programmers - you or I or someone else - will be very confused to see CI changes in a commit talking about json encoders.
Added this here, cause it fixes both CI and redash |
@AndrewChubatiuk Like @guidopetri says, iit'd be better to have a PR that just fixes CI (eg changing sha hash or whatever), and the custom encoder stuff can go in a separate PR. 😄 |
21049c9
to
93578f8
Compare
4f41e05
to
1b132b4
Compare
@AndrewChubatiuk @guidopetri k, I've merged that other PR to fix the CI branch problem. |
@AndrewChubatiuk Shouldn't this PR be passing CI now that the other one is merged and this one has been rebased? |
5fe222b
to
72555b2
Compare
@justinclift pushed unit test fixes |
@AndrewChubatiuk Excellent, thanks. 😄 |
@justinclift @guidopetri can we merge this to fix CI in master? |
redash/utils/json.py
Outdated
|
||
def __init__(self, **kwargs): | ||
self.encoders = [ | ||
r.custom_json_encoder for r in query_runners.values() if hasattr(r, "custom_json_encoder") and r.enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I notice this line seems to be the only actual change in this PR. @AndrewChubatiuk , please undo all the other changes - e.g. creating this json.py file and all the import changes, as well as the classmethod additions. Work like this doesn't make it easy to review code, nor does it make it easy to follow code when investigating issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, please explain this change in the PR description in two or three paragraphs, providing:
- context of why this change is necessary
- what led to this change (including links to all previous related PRs)
- what the current behavior is, and why it's wrong
- and what the intended behavior is.
Additionally, please describe how you've tested it. If you only have manual tests, then please add some kind of automated test with pytest or unittest to make sure that this does not break again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i cannot make this change without moving JSONEncoder to a separate file. It will lead to circular import problem as query_runners
variable, which is used to import custom json encoders is inside redash
module, which uses redash.utils
. JSONEncoder is inside redash.utils
module, which uses redash
module.
Regarding tests, I've tested it both manually and also e2e and unit tests have passed successfully
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guidopetri also updated PR description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you try making the import of query_runners
that you need within the JSONEncoder definition? I believe that will circumvent the circular import.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guidopetri commited in a way you want. you can check CI logs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that the current import location leads to a circular import. Please read my comment above more carefully - can we make the import within the JSONEncoder definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guidopetri tried to put imports, which cause circular dependencies issues, inside classes, but it didn't work. moved query_runners
to another module instead to have less changes comparing to moving json methods to a separate module
b151747
to
12e3064
Compare
e5b8bdd
to
3cd909e
Compare
3cd909e
to
7e110a6
Compare
from redash.query_runner import query_runners | ||
|
||
self.encoders = [r.custom_json_encoder for r in query_runners.values() if hasattr(r, "custom_json_encoder")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you can see, this change is much smaller and more readable than previously: only the essential was done to fix the issue at hand. We can move things away from the __init__.py
files in a later PR, but for now we need to fix the CI, so we shouldn't do any refactor changes if they're not necessary.
Merging now that we're passing the tests. The codecov isn't as important in this circumstance but we should improve it later. |
What type of PR is this?
custom json encoders import, which was introduced in #6687 and fixed in #6741 includes all encoders which leads to E2E test failure as mongodb dependencies are not installed during E2E test execution, but ObjectId is used inside mongodb custom encoder. this PR filters out encoders of disabled query runners
Description
How is this tested?
Related Tickets & Documents
Mobile & Desktop Screenshots/Recordings (if there are UI changes)