与其说是真正的解决方案,不如说是一个想法。假设您的数据如下所示:
data = [
{"foobar":
{"foo": 1, "bar": 2, "fozbaz": {
"foz": 0, "baz": {"b": -1, "a": -1, "z": -1}
}}}]
import json
with open("foobar.json", "w") as fw:
for record in data:
fw.write(json.dumps(record))
首先让我们加载它并检查架构:
>>> srdd = sqlContext.jsonFile("foobar.json")
>>> srdd.printSchema()
root
|-- foobar: struct (nullable = true)
| |-- bar: integer (nullable = true)
| |-- foo: integer (nullable = true)
| |-- fozbaz: struct (nullable = true)
| | |-- baz: struct (nullable = true)
| | | |-- a: integer (nullable = true)
| | | |-- b: integer (nullable = true)
| | | |-- z: integer (nullable = true)
| | |-- foz: integer (nullable = true)
现在我们按照Justin Pihony 的建议注册表并提取模式:
srdd.registerTempTable("srdd")
schema = srdd.schema().jsonValue()
我们可以使用类似下面的方法来扁平化模式,而不是扁平化数据:
def flatten_schema(schema):
"""Take schema as returned from schema().jsonValue()
and return list of field names with full path"""
def _flatten(schema, path="", accum=None):
# Extract name of the current element
name = schema.get("name")
# If there is a name extend path
if name is not None:
path = "{0}.{1}".format(path, name) if path else name
# It is some kind of struct
if isinstance(schema.get("fields"), list):
for field in schema.get("fields"):
_flatten(field, path, accum)
elif isinstance(schema.get("type"), dict):
_flatten(schema.get("type"), path, accum)
# It is an atomic type
else:
accum.append(path)
accum = []
_flatten(schema, "", accum)
return accum
添加小助手来格式化查询字符串:
def build_query(schema, df):
select = ", ".join(
"{0} AS {1}".format(field, field.replace(".", "_"))
for field in flatten_schema(schema))
return "SELECT {0} FROM {1}".format(select, df)
最后的结果:
>>> sqlContext.sql(build_query(schema, "srdd")).printSchema()
root
|-- foobar_bar: integer (nullable = true)
|-- foobar_foo: integer (nullable = true)
|-- foobar_fozbaz_baz_a: integer (nullable = true)
|-- foobar_fozbaz_baz_b: integer (nullable = true)
|-- foobar_fozbaz_baz_z: integer (nullable = true)
|-- foobar_fozbaz_foz: integer (nullable = true)
免责声明:我没有尝试深入研究架构结构,所以很可能有些情况没有被flatten_schema 涵盖。