Skip to content

Commit 68b5de7

Browse files
committed
fix(exports): convert bool values for SAV exports
1 parent 3472f15 commit 68b5de7

2 files changed

Lines changed: 41 additions & 3 deletions

File tree

onadata/libs/tests/utils/test_export_builder.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,37 @@ def test_zipped_sav_export_with_date_field(self):
727727

728728
shutil.rmtree(temp_dir)
729729

730+
def test_zipped_sav_export_with_bool_string_value(self):
731+
"""Boolean values in string fields are exported as strings."""
732+
md = """
733+
| survey |
734+
| | type | name | label |
735+
| | text | active | Active |
736+
737+
| choices |
738+
| | list name | name | label |
739+
"""
740+
survey = self.md_to_pyxform_survey(md, {"name": "exp"})
741+
data = [{"active": True}]
742+
export_builder = ExportBuilder()
743+
export_builder.set_survey(survey)
744+
with NamedTemporaryFile(suffix=".zip") as temp_zip_file:
745+
export_builder.to_zipped_sav(temp_zip_file.name, data)
746+
temp_zip_file.seek(0)
747+
temp_dir = tempfile.mkdtemp()
748+
with zipfile.ZipFile(temp_zip_file.name, "r") as zip_file:
749+
zip_file.extractall(temp_dir)
750+
751+
self.assertTrue(os.path.exists(os.path.join(temp_dir, "exp.sav")))
752+
753+
with SavReader(os.path.join(temp_dir, "exp.sav"), returnHeader=True) as reader:
754+
rows = list(reader)
755+
self.assertTrue(len(rows) > 1)
756+
self.assertEqual(_str_if_bytes(rows[0][0]), "active")
757+
self.assertEqual(_str_if_bytes(rows[1][0]), "True")
758+
759+
shutil.rmtree(temp_dir)
760+
730761
# pylint: disable=invalid-name
731762
def test_zipped_sav_export_dynamic_select_multiple(self):
732763
md = """

onadata/libs/utils/export_builder.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,9 +1440,16 @@ def to_zipped_sav(self, path, data, *args, **kwargs):
14401440
def write_row(row, sav_writer, fields):
14411441
# replace character for osm fields
14421442
fields = [field.replace(":", "_") for field in fields]
1443-
sav_writer.writerow(
1444-
[encode_if_str(row, field, sav_writer=sav_writer) for field in fields]
1445-
)
1443+
record = []
1444+
for field, var_name in zip(fields, sav_writer.varNames):
1445+
value = encode_if_str(row, field, sav_writer=sav_writer)
1446+
if (
1447+
isinstance(value, bool)
1448+
and sav_writer.varTypes[var_name] != SAV_NUMERIC_TYPE
1449+
):
1450+
value = str(value)
1451+
record.append(value)
1452+
sav_writer.writerow(record)
14461453

14471454
sav_defs = {}
14481455

0 commit comments

Comments
 (0)