Skip to content

Commit 2f34c5a

Browse files
bolkedebruinWillAyd
andcommitted
Fix TypeError when pulling field that is None
If normalizing a jsonstruct a field can be set to None due to a schema change. Co-Authored-By: William Ayd <[email protected]>
1 parent 1083472 commit 2f34c5a

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

doc/source/whatsnew/v1.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ I/O
792792
- Bug in :func:`read_json` where default encoding was not set to ``utf-8`` (:issue:`29565`)
793793
- Bug in :class:`PythonParser` where str and bytes were being mixed when dealing with the decimal field (:issue:`29650`)
794794
- :meth:`read_gbq` now accepts ``progress_bar_type`` to display progress bar while the data downloads. (:issue:`29857`)
795-
-
795+
- Bug in :func:`pandas.io.json.json_normalize` where a missing value in the location specified by `record_path` would raise a ``TypeError`` (:issue:`30148`)
796796

797797
Plotting
798798
^^^^^^^^

pandas/io/json/_normalize.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from collections import defaultdict
55
import copy
6-
from typing import DefaultDict, Dict, List, Optional, Union
6+
from typing import Any, DefaultDict, Dict, Iterable, List, Optional, Union
77

88
import numpy as np
99

@@ -228,14 +228,17 @@ def json_normalize(
228228
Returns normalized data with columns prefixed with the given string.
229229
"""
230230

231-
def _pull_field(js, spec):
232-
result = js
231+
def _pull_field(js: Dict[str, Any], spec: Union[List, str]) -> Iterable:
232+
result: Any = js
233233
if isinstance(spec, list):
234234
for field in spec:
235235
result = result[field]
236236
else:
237237
result = result[spec]
238238

239+
if not isinstance(result, Iterable):
240+
result = []
241+
239242
return result
240243

241244
if isinstance(data, list) and not data:

pandas/tests/io/json/test_normalize.py

+13
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,19 @@ def test_nested_flattening_consistent(self):
463463
# They should be the same.
464464
tm.assert_frame_equal(df1, df2)
465465

466+
def test_nonetype_record_path(self, nulls_fixture):
467+
# see gh-30148
468+
# should not raise TypeError
469+
result = json_normalize(
470+
[
471+
{"state": "Texas", "info": nulls_fixture},
472+
{"state": "Florida", "info": [{"i": 2}]},
473+
],
474+
record_path=["info"],
475+
)
476+
expected = DataFrame({"i": 2}, index=[0])
477+
tm.assert_equal(result, expected)
478+
466479

467480
class TestNestedToRecord:
468481
def test_flat_stays_flat(self):

0 commit comments

Comments
 (0)