diff --git a/pandas/io/json/_table_schema.py b/pandas/io/json/_table_schema.py index 7879be18b52c9..b5ee32220d7b7 100644 --- a/pandas/io/json/_table_schema.py +++ b/pandas/io/json/_table_schema.py @@ -372,6 +372,11 @@ def parse_table_schema(json, precise_float: bool) -> DataFrame: pandas.read_json """ table = ujson_loads(json, precise_float=precise_float) + fields = table["schema"]["fields"] + + if any(not isinstance(field["name"], str) for field in fields): + raise ValueError("All column names must be strings when using orient='table'.") + col_order = [field["name"] for field in table["schema"]["fields"]] df = DataFrame(table["data"], columns=col_order)[col_order] diff --git a/pandas/tests/io/json/test_json_table_schema.py b/pandas/tests/io/json/test_json_table_schema.py index 7936982e4a055..dba615f532d70 100644 --- a/pandas/tests/io/json/test_json_table_schema.py +++ b/pandas/tests/io/json/test_json_table_schema.py @@ -881,3 +881,24 @@ def test_read_json_table_orient_period_depr_freq(self, freq): out = StringIO(df.to_json(orient="table")) result = pd.read_json(out, orient="table") tm.assert_frame_equal(df, result) + + def test_read_json_table_non_string_column_names(self) -> None: + bad_json = json.dumps( + { + "schema": { + "fields": [ + {"name": 0, "type": "integer"}, + {"name": 1, "type": "string"}, + ], + "primaryKey": [], + "pandas_version": "1.0.0", + }, + "data": [[1, "a"], [2, "b"]], + } + ) + + with pytest.raises( + ValueError, + match="All column names must be strings when using orient='table'", + ): + pd.read_json(StringIO(bad_json), orient="table")