-
Notifications
You must be signed in to change notification settings - Fork 21
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
'get_aggregation_unit' action and 'aggregation_unit' params for all spatial aggregates #5278
Conversation
…tent with other query kinds
Codecov Report
@@ Coverage Diff @@
## master #5278 +/- ##
===========================================
- Coverage 93.43% 76.15% -17.28%
===========================================
Files 276 277 +1
Lines 10724 10847 +123
Branches 1274 1284 +10
===========================================
- Hits 10020 8261 -1759
- Misses 576 2333 +1757
- Partials 128 253 +125
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
|
||
In a new file 'flowmachine/core/server/query_schemas/my_query.py', define a new class `MyQueryExposed`. This class is responsible for constructing the appropriate `MyQuery` object from parameter values supplied in an API call. | ||
|
||
There are two options here: if users should be able to select a random sample of the rows from this query result, the exposed query class should inherit from [`BaseExposedQueryWithSampling`](../flowmachine/flowmachine/core/server/query_schemas/base_query_with_sampling/#class-baseexposedquerywithsampling) (this is usually appropriate for _individual-level_ queries). If it does not make sense to allow random sampling of the query result (as is usually the case for _aggregate_ queries), the exposed query class should inherit from [`BaseExposedQuery`](../flowmachine/flowmachine/core/server/query_schemas/base_exposed_query/#class-baseexposedquery). |
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.
We might consider changing the names of these really.
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.
Yes, could do. What would you suggest?
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 was wondering about BaseIndividualQuery
and BaseAggregateQuery
, but I'm not sure it makes sense given that it may not be universally the case that these are the appropriate bases.
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.
Hmm, yes, I don't know whether it will always be the case that we'd want to allow sampling for all non-aggregates and never for aggregates.
I wonder whether we'd be better-off rolling the sampling stuff into BaseExposedQuery
(i.e. apply sampling if there's a sampling parameter, otherwise don't), and turning BaseQueryWithSamplingSchema
into a mixin - then we don't have to worry about having two different bases.
For this action handler the `action_params` are exactly the query kind plus the | ||
parameters needed to construct the query. | ||
""" | ||
def _load_query_object(params: dict) -> "BaseExposedQuery": |
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.
Might make sense to make this a class method on BaseExposedQuery
?
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.
Not straightforward without leading to circular imports. And on reflection, I'm not sure it makes all that much sense anyway - the core of this function is just FlowmachineQuerySchema().load(params)
; the rest is just catching appropriate errors and manipulating them into a form that's convenient for constructing an appropriate ZMQReply, so I think it makes sense to keep this alongside the action handlers.
query_kind = fields.String(validate=OneOf(["active_at_reference_location_counts"])) | ||
unique_locations = fields.Nested(UniqueLocationsSchema()) | ||
reference_locations = fields.Nested(ReferenceLocationSchema()) | ||
query_kind = fields.String(validate=OneOf([__model__.query_kind]), required=True) |
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 this be moved into BaseSchema
?
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.
Unfortunately not, I think - the validator needs to get the query kind from __model__.query_kind
, and this has to be set when defining the class. It would be neater if we could move this into BaseSchema
, but I can't see a way to do it.
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.
Could use __init_subclass__
to attach it to the class?
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.
Oh true, yes, that should work.
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.
Hmm, no, doesn't seem to work. I tried adding
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
if hasattr(cls, "__model__"):
cls.query_kind = fields.String(validate=OneOf([cls.__model__.query_kind]), required=True)
and while subclasses get a query_kind
class attribute as expected, it doesn't get included as a field to be deserialised. Looks like marshmallow is doing some magic behind the scenes that doesn't play nicely with this approach.
flowmachine/flowmachine/core/server/query_schemas/aggregation_unit.py
Outdated
Show resolved
Hide resolved
|
||
In a new file 'flowmachine/core/server/query_schemas/my_query.py', define a new class `MyQueryExposed`. This class is responsible for constructing the appropriate `MyQuery` object from parameter values supplied in an API call. | ||
|
||
There are two options here: if users should be able to select a random sample of the rows from this query result, the exposed query class should inherit from [`BaseExposedQueryWithSampling`](../flowmachine/flowmachine/core/server/query_schemas/base_query_with_sampling/#class-baseexposedquerywithsampling) (this is usually appropriate for _individual-level_ queries). If it does not make sense to allow random sampling of the query result (as is usually the case for _aggregate_ queries), the exposed query class should inherit from [`BaseExposedQuery`](../flowmachine/flowmachine/core/server/query_schemas/base_exposed_query/#class-baseexposedquery). |
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 was wondering about BaseIndividualQuery
and BaseAggregateQuery
, but I'm not sure it makes sense given that it may not be universally the case that these are the appropriate bases.
…unit.py Co-authored-by: Jonathan Gray <[email protected]>
Test summaryRun details
View run in Cypress Dashboard ➡️ This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard |
Closes #5141, #4816
I have:
Description
Adds a new flowmachine server action,
get_aggregation_unit
, which returns the aggregation unit associated with a spatial aggregate query (orNone
if the query is not a spatial aggregate). To support this, all exposed query class instances corresponding to a spatial aggregate query now have anaggregation_unit
attribute or property.Also adds a dump-only
aggregation_unit
parameter to all spatial aggregates that do not have an explicitaggregation_unit
parameter - a dump-only field is not accepted as an input parameter, but it is included in the API spec (marked as "read-only") so that FlowAPI can use this parameter to determine whether a query kind is a spatial aggregate when generating permission scopes. The dump-onlyaggregation_unit
fields also mean that theaggregation_unit
property of an exposed query will be included if the query is serialised - while that's a nice feature, it's not something we currently rely on for anything.Adds a docs section on exposing a new query kind, since there are an increasing number of steps that need to be included in an exposed query.
Also a few changes to query schemas that are not directly related to the original aims of this PR:
OneOfQuerySchema
(subclass ofOneOfSchema
) for nesting a choice of multiple sub-query schemas. Consequences are that all exposed query classes now need aquery_kind
class attribute, and we no longer need a workaround in FlowAPI to markquery_kind
parameters as required.Direction
field, to replace the duplicated code used fordirection
fields in several query schemas