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

Return flow data results for merged datasets #1773

Merged
merged 10 commits into from Jul 17, 2020

Conversation

DavisRayM
Copy link
Contributor

@DavisRayM DavisRayM commented Jan 29, 2020

Changes / Features implemented

  • Set uuid for MergedXForm on save
  • Return flow data results for merged datasets
  • Add test test_retrieve_responses_merged_dataset
  • Enable one to retrieve a FLOIP Package or response using the complete uuid4 string or its hex version
  • Add migration to set default uuid for XForms that are missing the field.
  • Return complete uuid4 strings on the floip viewset
  • Bump pyfloip version

Steps taken to verify this change does what is intended

  • Added test to ensure data is returned
  • Modified tests to ensure UUID is returned from the Merged XForm Endpoint

QA Checklist

  • Able to retrieve a MergedXForm and it's data from the FLOIP Endpoint.

Step 1: Retrieve MergedXForm UUID from the XForm endpoint /api/v1/forms/<form_id>
Step 2: Access the FLOIP Package http://localhost:8000/api/v1/flow-results/packages/<uuid>. Should return package information for the MergedXForm
Step 3: Access the FLOIP Responses http://localhost:8000/api/v1/flow-results/packages/<uuid>/responses. Should return all the answers to the form questions as JSON Objects
Things to consider: Forms with media, Forms with nested groups

  • uuid4 strings are used to identify packages(All ids returned by the endpoint should be uuid4). A uuid4 string can be identified by its 32 hex characters and 4 dashes

Closes #1643

@DavisRayM
Copy link
Contributor Author

DavisRayM commented Jan 29, 2020

Side effects of implementing the PR as is

  • Need to find a way to set uuid for all pre-existing MergedXForms. Non breaking issue

The pre-existing MergedXForms defaulted theuuid to an empty string(Inherits the field from XForm). We may need to set the uuid fields for this feature/fix to work on merged datasets generated before this is implemented.

Screenshot 2020-01-29 at 13 10 20

@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch from 57c4c86 to ea543e9 Compare January 29, 2020 10:15
response.data['attributes']['responses'])
# The transportation form(self.xform) contains 11 responses
# Assert that the responses are returned
self.assertEqual(len(response.data['attributes']['responses']), 11)
Copy link
Contributor Author

@DavisRayM DavisRayM Jan 29, 2020

Choose a reason for hiding this comment

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

Chose to use the number of responses returned(11) for this test due to erratic time values returned in the responses.

@DavisRayM DavisRayM changed the title Fix issue where flow data results for Merged datasets would not be returned Return flow data results for merged datasets Jan 29, 2020
@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch from ea543e9 to 10d560d Compare January 29, 2020 10:52
@DavisRayM DavisRayM requested review from ivermac and pld January 29, 2020 13:01
@DavisRayM
Copy link
Contributor Author

DavisRayM commented Jan 29, 2020

Side effects of implementing the PR as is

* Need to find a way to set `uuid` for all pre-existing MergedXForms. _Non breaking issue_

The pre-existing MergedXForms defaulted to an empty string(Inherits the field from XForm) as the uuid we may need to set the uuid fields for these xforms somehow.

Screenshot 2020-01-29 at 13 10 20

Using a data migration to solve the missing uuid field value may be a bit painful for production servers since the XForm model it inherits from is usually quite bulky.

Other options we have is to set the values lazily either:

  • When a merged dataset is retrieved by the forms endpoint
  • When .save() is called on a dataset

Opinions on a favorable way to proceed ?

CC: @pld @ivermac

@ukanga
Copy link
Member

ukanga commented Mar 9, 2020

Using a data migration to solve the missing uuid field value may be a bit painful for production servers since the XForm model it inherits from is usually quite bulky.

Other options we have is to set the values lazily either:

  • When a merged dataset is retrieved by the forms endpoint
  • When .save() is called on a dataset

Opinions on a favorable way to proceed ?

I will recommend the data migration as well as the default value for the UUID field. This will be the data migration first and a second migration that sets the default value.

lincmba
lincmba previously approved these changes Mar 9, 2020
Copy link
Member

@pld pld left a comment

Choose a reason for hiding this comment

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

can you please add a test for the generation of default IDs

@DavisRayM DavisRayM changed the title Return flow data results for merged datasets [WIP] Return flow data results for merged datasets Mar 9, 2020
@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch from 20c3a0c to a3f7fd2 Compare March 11, 2020 07:30
# Always have uuids.
# Assert that set_uuid is called with an object
# that already has a uuid.
self.assertEqual(set_uuid_mock.call_count, 1)
Copy link
Contributor Author

@DavisRayM DavisRayM Mar 11, 2020

Choose a reason for hiding this comment

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

The DataDictionary model always sets uuid for XForms. Sadly, since the MergedXForm model inherits from the XForm model directly it doesn't have the uuid set...(And probably a few other custom processing steps ?)

I wonder if we should just modify the save method of the MergedXForm model to set the uuid ? I prefer having the uuid set directly from the parent class(XForm)

Copy link
Member

Choose a reason for hiding this comment

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

Yes, let's have a UUID for the merged form.

@DavisRayM
Copy link
Contributor Author

can you please add a test for the generation of default IDs

I've added a test to test the generation of the default uuids in the latest commits. Please have a look.

@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch 2 times, most recently from c6b2676 to 84c7033 Compare March 11, 2020 07:37
@DavisRayM DavisRayM changed the title [WIP] Return flow data results for merged datasets Return flow data results for merged datasets Mar 11, 2020
# Assert that the uuid is not empty and is
# 32 characters in length
self.assertNotEqual(uuid, '')
self.assertEqual(len(uuid), 32)
Copy link
Contributor Author

@DavisRayM DavisRayM Mar 11, 2020

Choose a reason for hiding this comment

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

uuid4 is always 36 characters (32 hex digits + 4 dashes).

Decided to use the default way the uuid field is set for DataDictionary objects to not diverge from the norm; Generates uuids without the dashes(only hex)

@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch 2 times, most recently from b97e3cd to a1ef783 Compare March 18, 2020 11:44
Copy link
Contributor

@ivermac ivermac left a comment

Choose a reason for hiding this comment

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

Code looks good to me but I'd like @pld or @ukanga to review as well

@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch from a1ef783 to e816e11 Compare March 18, 2020 12:21
@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch from 33e1398 to dd535d0 Compare May 22, 2020 14:04
Add the 'uuid' field from the MergedXForm model to the tuple of fields
to serialize in the MergedXFormSerializer.
- Limit 'uuid' field to write only
Set the 'uuid' field on MergedXForms on save
@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch 2 times, most recently from da3520e to 8820db3 Compare July 13, 2020 14:24
@DavisRayM DavisRayM removed the QA+ PR passed QA testing label Jul 13, 2020
@DavisRayM DavisRayM changed the title [WIP] Return flow data results for merged datasets Return flow data results for merged datasets Jul 14, 2020
@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch 2 times, most recently from a1b7221 to 8a2a4a2 Compare July 15, 2020 06:36
@faith-mutua
Copy link

@DavisRayM Flow data results for merged datasets now have data.

@DavisRayM DavisRayM force-pushed the 1643-flow-date-result-merged-dataset branch from 8a2a4a2 to 6e10034 Compare July 15, 2020 07:52
@faith-mutua faith-mutua added the QA+ PR passed QA testing label Jul 15, 2020
Copy link
Contributor

@ivermac ivermac left a comment

Choose a reason for hiding this comment

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

Generally looks good to me. I have one question though

Comment on lines 8 to 16
def generate_uuid_if_missing(apps, schema_editor):
"""
Generate uuids for XForms without them
"""
XForm = apps.get_model('logger', 'XForm')

for form in XForm.objects.filter(uuid=''):
form.uuid = get_uuid()
form.save()
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't this be expensive when running migrations - even though it might be one time? Can we do this in the XForm's save function; check if that form has a uuid and set one if it doesn't exist.
I guess my worry is just the app going through all XForms checking which one doesn't have a uuid

Copy link
Contributor

Choose a reason for hiding this comment

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

May be not check on the XForm's instance save function but where the uuid is required

Copy link
Contributor Author

@DavisRayM DavisRayM Jul 15, 2020

Choose a reason for hiding this comment

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

I'm not entirely sure if this query would be expensive to run(I'll try analyzing the query on a large database and get back to you). The XForm save function has a check to set the UUID when missing through the DataDictionary model.

The main reason this was included was because of MergedXForms since they're not created through the DataDictionary model. But, I've also modified the MergedXForm save to set it when missing...

I'm not sure at the moment about when MergedXForms are updated/saved again after creation. I'll update this once I research a bit more

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool. I guess i'm fine if retrieving xforms without uuid won't be expensive

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 query isn't expensive to run. The index we currently have on the UUID field speeds up the query quite a lot

Screenshot 2020-07-15 at 15 26 42

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool

@ivermac ivermac self-requested a review July 15, 2020 13:16
ivermac
ivermac previously approved these changes Jul 15, 2020
"""
XForm = apps.get_model('logger', 'XForm')

for form in XForm.objects.filter(uuid=''):
Copy link
Member

Choose a reason for hiding this comment

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

We tend to use xform instead of form as a variable of an XForm model object. Can we keep the same for consistency?

Copy link
Contributor Author

@DavisRayM DavisRayM Jul 17, 2020

Choose a reason for hiding this comment

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

Yes, I've changed this to xform in the latest commits

Add a data migration that generates 'uuid' values for XForms that do not
have a uuid
Return FLOIP results for merged datasets; Retrieve all instances
attached to the forms that make up the MergedXForm
Bump pyfloip version to commit 3c980eb184069ae7c3c9136b18441978237cd41d
Support both uuid4 and uuid4 hex string on FLOIP Endpoint; Allow users
to use the string to retrieve and publish FLOIP Responses & Results
Utilize uuid4 string when generating 'Location' header values for the
FLOIP endpoint
Add ReadOnlyUUIDField custom serializer field to serializer UUID fields
@DavisRayM DavisRayM merged commit 762ec1a into master Jul 17, 2020
@DavisRayM DavisRayM deleted the 1643-flow-date-result-merged-dataset branch July 17, 2020 08:53
@DavisRayM DavisRayM mentioned this pull request Jul 28, 2020
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
QA+ PR passed QA testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flow data results in a merged dataset is blank
6 participants