diff --git a/pandas/io/json/_normalize.py b/pandas/io/json/_normalize.py index 459b4035627cc..bbe70544ec916 100644 --- a/pandas/io/json/_normalize.py +++ b/pandas/io/json/_normalize.py @@ -490,6 +490,8 @@ def _pull_records(js: dict[str, Any], spec: list | str) -> list: meta_keys = [sep.join(val) for val in _meta] def _recursive_extract(data, path, seen_meta, level: int = 0) -> None: + if data is None: + return if isinstance(data, dict): data = [data] if len(path) > 1: diff --git a/pandas/tests/io/json/test_normalize.py b/pandas/tests/io/json/test_normalize.py index 316f262885424..73b8ece625237 100644 --- a/pandas/tests/io/json/test_normalize.py +++ b/pandas/tests/io/json/test_normalize.py @@ -582,6 +582,29 @@ def test_top_column_with_leading_underscore(self): tm.assert_frame_equal(result, expected) + def test_column_with_none(self): + # 53719 + data = { + "root": [ + { + "id": 1, + "nested_field": [{"nested_field_id": 1}], + }, + {"id": 2, "nested_field": None}, + ] + } + result = json_normalize( + data, + record_path=["root", "nested_field"], + ) + expected = DataFrame( + { + "nested_field_id": [1], + } + ) + + tm.assert_frame_equal(result, expected) + class TestNestedToRecord: def test_flat_stays_flat(self):