-
-
Notifications
You must be signed in to change notification settings - Fork 338
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
Replace filtering API; includes support for filtering numbers #1069
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1069 +/- ##
==========================================
+ Coverage 92.81% 93.33% +0.52%
==========================================
Files 112 113 +1
Lines 4021 4052 +31
==========================================
+ Hits 3732 3782 +50
+ Misses 289 270 -19
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
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.
the
column_reference
, whose parameter is a plain string denoting the column's name;
We should be using column ID as the primary way to refer to a column, we're in the process of switching the entire API to do this, see:
- Replace column index usage with attnums and Column model
id
#839 - Modify records API to use column id instead of column name #896
- Modify constraints API to use column id instead of column name #898
The key should be column_id
instead of column_reference
for clarity.
I'll review in more detail once this is fixed.
@dmos62 Please let me know when this PR is ready for frontend changes. I'll take it up. |
@kgodey I'm aware of the move to using column IDs. It's not yet in master though, or is it? Should I refactor this PR to use column ids? I'll rename Edit: I looked through the mentioned issues and saw that we're moving to ids gradually (endpoint by endpoint). I'll refactor to use IDs. |
@silentninja is working on these, hopefully they should be in |
Added support for specifying columns via their Django IDs. Now the JSON expected by the {"and": [
{"empty": [
{"column_id": [1]},
]},
{"equal": [
{"column_id": [3]},
{"literal": ["some_literal_value"]},
]},
]} The difference from the sample posted in the first post is that DetailsMade DB layer unaware of Django IDs, by preprocessing the passed DBFunction JSON specification (for example to the |
Why is |
@kgodey Edit: To put it another way, it's easier to say that the parameters are always a list. This might become less awkward if/when named parameters are introduced. |
@dmos62 To make the API easier to read, I recommend dropping the list from |
@kgodey I replied that I'd make the change, but then thought about it some more and came to the conclusion that it's not a good idea (and deleted that reply). Having two forms for passing parameters grows the code complexity more than you'd expect, since we're parsing the function JSON spec twice. Once to rewrite IDs to names and again to instantiate a I don't think that the readability improvement is significant enough to justify that. Plus, I'd like to keep the syntax as simple as possible. I have considered switching syntax format from Edit: this is all the input I have on this; I leave it up to you to make the call. |
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.
@dmos62 This looks good overall, added some minor comments. I'm fine with the current API spec for now if it's going to result in repeated logic, but I did have a question about why we couldn't put the logic in a single place.
Could you open a separate GitHub issue to reevaluate the filtering API spec with a link to this discussion? It should go in the API v1 milestone (which is post-alpha).
) | ||
|
||
|
||
def _rewrite(column_ids_to_names, spec_or_literal): |
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 only see the JSON spec being parsed here - couldn't you check for single parameters here and convert them to a list during this rewrite?
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.
The other place is db.functions.operations.deserialize
. It's true that we could convert the single-parameter to a list here and the db.functions.operations.deserialize
routines would be none the wiser. That would diverge the two (somewhat implicit) syntaxes more than I'd like though. The difference between them now is just the additional column_id
DBFunction. It's not an actual DBFunction but I'm simulating it with this rewrite routine and the user shouldn't be able to tell the difference. Changing how one of these handles parameters (but not the other) is more complexity than I'd like.
There's some alternatives I can envision. Like being able to extend the set of DBFunctions used when parsing. Then the mathesar namespace/layer would tell the parsing routines to also use this custom ColumnID
DBFunction that will convert ids to names when being turned into an SA expression. That way the db layer is unaware of column ids and that would centralize all the parsing into one place.
Not sure it's worth the effort right now.
@kgodey Renamed |
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.
Looks good to me. I assume @pavish needs to make frontend changes before we merge?
I'll get started on the frontend changes. I'll not be using the I have a couple things to confirm before I begin:
Please let me know if these assumptions are correct. |
The frontend changes needed for this PR has a good deal of overlap with the frontend changes needed for #1047 (Changing column names to ids). The column name -> id change needs to be implemented on the frontend before we can update the filter format. How do we proceed on this? I believe frontend changes for #1047 will take some time, since it will involve some refactoring. Shall we merge this PR and:
Both these options will involve us having to deal with breaking functionality in master for a while. |
@pavish I'm fine with breaking things in |
@pavish Does that mean this PR can be merged as-is? |
@pavish Yes, your assumptions are correct. I've forgotten to post a summary of that for you, sorry! This is the final format and the This PR shouldn't block any other developers for a while, so I'd say feel free to merge in whichever order you prefer. @kgodey @pavish @seancolsen Would it make sense to merge into a dedicated branch (that is not master) until it's not broken anymore and then merge that into master, thus not breaking master? |
I don't think it's worth the fuss at this point since no one is using |
Fixes #385
Related to #1028
This is a continuation of the #1061 PR. Contains 2 major changes:
/api/ui/v0/database/0/filters/
;records
query param is nowfilter
, notfilters
(singular, not plural);duplicate_only
operation from a filter into a query param (see Improve support for finding duplicate rows #1028 for some context); to be clear, this had to be done, there wasn't a coherent way to consider it a Mathesar filter.Also, includes number filters necessary to fulfil requirements in #385. Actually, it's the previous PR, #1061, that included these filters, but now they will be usable.
Technical details
Filters are specified by frontend in the function API format:
The expected data structure is made up of dicts containing one (and only one) key-value pair each. The key is the filter id, and the value is always a list of parameters. Every parameter is either a nested filter, or a string/number when it's the sole parameter to
literal
orcolumn_reference
.There are 5 "special filters" that are not declared with the rest (in
/api/ui/v0/database/0/filters/
) and have to be hardcoded:and
,or
,not
; their syntax is equivalent to that of regular filters;column_reference
, whose parameter is a plain string denoting the column's name;literal
, whose parameter is some non-collection JSON primitive whose value will be used verbatim (see parameters of theequal
sub-filter above).column_reference
andliteral
"special filters" must always be used when you want to pass a column reference or a literal. The API should throw an error otherwise.New filter API uses the functions API under-the-hood. Filters are actually
DBFunction
s presented in a simplified way. The syntax for submitting filters to backend is actually just the function API syntax. The filter API could be seen as a thin layer on top of the function. API.Checklist
Update index.md
).master
branch of the repositoryvisible errors.
Developer Certificate of Origin
Developer Certificate of Origin