diff --git a/src/tablib/core.py b/src/tablib/core.py index b0b56fd2..80945616 100644 --- a/src/tablib/core.py +++ b/src/tablib/core.py @@ -371,7 +371,10 @@ def _set_dict(self, pickle): self.wipe() self.headers = list(pickle[0].keys()) for row in pickle: - self.append(Row(list(row.values()))) + # Align values to the headers by key, not by position: JSON + # object member order is not significant (RFC 8259) and dict + # keys may legitimately differ in order across records. + self.append(Row([row.get(header) for header in self.headers])) else: raise UnsupportedFormat(error_details) diff --git a/tests/test_tablib.py b/tests/test_tablib.py index 32f0e4b1..b6852529 100755 --- a/tests/test_tablib.py +++ b/tests/test_tablib.py @@ -1693,6 +1693,14 @@ def test_json_import_set(self): self.assertEqual(json.loads(_json), json.loads(data.json)) + def test_json_import_heterogeneous_key_order(self): + """Records with keys in a different order must align by key, not position.""" + ds = tablib.Dataset() + ds.json = '[{"name": "alice", "age": 30}, {"age": 25, "name": "bob"}]' + self.assertEqual(list(ds.headers), ['name', 'age']) + self.assertEqual(ds[0], ('alice', 30)) + self.assertEqual(ds[1], ('bob', 25)) + def test_json_export(self): """Verify exporting dataset object as JSON"""