-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add utility to update xform export repeat columns from instance * refactor code * reset repeat_instances[repeat] if incoming repeat max is greater * update code comments * refactor code * refactor code * refactor comment * refactor code * update code comment * register repeats on Instance create or update * add tests * add test * disregard form version when registering repeats * use registered repeats when generating CSV export * fix registered repeats invalid export * enhance use of registered repeats to generate CSV * handle missing repeats in registered repeats * refactor code * refactor code * consider previous submissions when creating new register * refactor code * create repeat register if Instance has no repeats * enhance tests * fix cyclic dependency error * fix lint warning fix unnecessary-dict-index-lookup * suppress lint warning suppress too-many-lines * do not fall back to data if repeat unregistered * rename export_repeat_columns * fix cyclic dependency * refactor code * refactor code * fix flaky test * fix failing tests * refactor test * refactor test * remove lint warning ignore * rename symbol * refactor code * refactor code * fix flaky test * add doc strings * add doc strings * fix failing tests * do not register repeat if instance not approved * refactor code * rename symbol * rename symbol * feat: add export_data management command * add codetiming dependency * address lint warning * fix lint warning line too long * add missing class docstring * fix incorrect command output --------- Co-authored-by: Ukang'a Dickson <[email protected]>
- Loading branch information
1 parent
03436fa
commit f9caeb5
Showing
18 changed files
with
1,170 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,3 +88,5 @@ tags | |
.eggs | ||
sonar-project.properties | ||
.scannerwork | ||
|
||
*.er |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Management command to export data from a form in CSV format. | ||
""" | ||
|
||
from django.core.management.base import BaseCommand | ||
|
||
from codetiming import Timer | ||
|
||
from onadata.apps.logger.models.xform import XForm | ||
from onadata.apps.viewer.models.export import Export | ||
from onadata.libs.utils.export_tools import generate_export | ||
|
||
|
||
class Command(BaseCommand): | ||
"""Export data from a form in CSV format""" | ||
|
||
help = "Exports data from a form in CSV format" | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument("form_id", type=int) | ||
|
||
def handle(self, *args: str, **options: str): | ||
self.stdout.write(self.style.SUCCESS("Exporting ...")) | ||
form_id = options["form_id"] | ||
try: | ||
xform = XForm.objects.get(pk=form_id) | ||
except XForm.DoesNotExist: | ||
self.stderr.write( | ||
self.style.ERROR(f"There is no form with id {form_id} present.") | ||
) | ||
else: | ||
with Timer() as timer: | ||
export = generate_export(Export.CSV_EXPORT, xform) | ||
elapsed_time = timer.last | ||
msg = ( | ||
f"The file {export.full_filepath} was exported in " | ||
f"{elapsed_time:.2f} seconds." | ||
) | ||
self.stdout.write(self.style.NOTICE(msg)) | ||
plural_or_singular = ( | ||
"submission" if xform.num_of_submissions == 1 else "submissions" | ||
) | ||
msg = ( | ||
f"{export.pk}: Exporting {xform.num_of_submissions} " | ||
f'{plural_or_singular} of the form "{xform.title}"' | ||
) | ||
self.stdout.write(self.style.SUCCESS(msg)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
onadata/apps/logger/tests/management/commands/test_export_data.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Tests for the onadata.apps.logger.management.commands.export_data module. | ||
""" | ||
|
||
from io import StringIO | ||
|
||
from django.core.management import call_command | ||
from django.core.management.base import CommandError | ||
|
||
from onadata.apps.main.tests.test_base import TestBase | ||
from onadata.apps.viewer.models.export import Export | ||
|
||
|
||
class ExportDataTest(TestBase): | ||
"""Tests for the export_data management command.""" | ||
|
||
def test_command_output(self): | ||
"""Test the output of the export_data management command.""" | ||
output = StringIO() | ||
error_output = StringIO() | ||
with self.assertRaisesMessage( | ||
CommandError, | ||
expected_message="Error: the following arguments are required: form_id", | ||
): | ||
_ = call_command("export_data", stdout=output) | ||
|
||
_ = call_command("export_data", 12300, stdout=output, stderr=error_output) | ||
self.assertIn("Exporting ...", output.getvalue()) | ||
self.assertIn( | ||
"There is no form with id 12300 present.", error_output.getvalue() | ||
) | ||
self._publish_transportation_form_and_submit_instance() | ||
export_count = Export.objects.filter().count() | ||
_ = call_command( | ||
"export_data", self.xform.pk, stdout=output, stderr=error_output | ||
) | ||
self.assertIn( | ||
f'Exporting 1 submission of the form "{self.xform.title}"', | ||
output.getvalue(), | ||
) | ||
# confirm a new export record was created. | ||
self.assertEqual(Export.objects.filter().count(), export_count + 1) | ||
export = Export.objects.filter( | ||
xform_id=self.xform.pk, export_type=Export.CSV_EXPORT | ||
).latest("created_on") | ||
self.assertIn( | ||
f"The file {export.full_filepath} was exported in", | ||
output.getvalue(), | ||
) |
Oops, something went wrong.