Python 创建特定于数据帧的架构:以大写字母开头的StructField

Python 创建特定于数据帧的架构:以大写字母开头的StructField,python,pyspark,schema,azure-databricks,pyspark-dataframes,Python,Pyspark,Schema,Azure Databricks,Pyspark Dataframes,我为这篇冗长的帖子道歉,因为它看起来很简单,但我想给出完整的上下文 在DataRicks中,我基于特定的模式定义创建一个数据“行”,然后将该行插入一个空数据框(也基于相同的特定模式) 架构定义如下所示: myschema_xb = StructType( [ StructField("_xmlns", StringType(), True), StructField("_Version", DoubleType(), True), StructField("MyIds

我为这篇冗长的帖子道歉,因为它看起来很简单,但我想给出完整的上下文

在DataRicks中,我基于特定的模式定义创建一个数据“行”,然后将该行插入一个空数据框(也基于相同的特定模式)

架构定义如下所示:

myschema_xb = StructType(
  [
    StructField("_xmlns", StringType(), True),
    StructField("_Version", DoubleType(), True),
    StructField("MyIds",
      ArrayType(
        StructType(
          [
            StructField("_ID", StringType(), True),
            StructField("_ID_Context", StringType(), True),
            StructField("_Type", LongType(), True),
          ]
        ),
        True
      ),
      True
    ),
  ]
)
因此,行条目是:

myRow = Row(
    _xmlns="http://some.where.com",
    _Version=12.3,
    MyIds=[
        Row(
          _ID="XY",
          _ID_Context="Exxwhy",
          _Type=9
        ),
        Row(
          _ID="9152",
          _ID_Context="LNUMB",
          _Type=21
        ),
    ]
)
最后,databricks笔记本代码为:

mydf = spark.createDataFrame(sc.emptyRDD(), myschema_xb)
rows = [myRow]
rdf = spark.createDataFrame(rows, myschema_xb)
appended = mydf.union(rdf)
调用
rdf=spark.createDataFrame(rows,myschema_xb)
会导致异常:

ValueError:StructType为意外元组“h”

现在我想知道的是,如果我将元素
myid
更改为
myid
(即小写的第一个字母),代码可以工作,并且我的新数据框(
追加的
)只有一行数据

这个异常是什么意思&当我改变元素的大小写时,为什么它会消失

(仅供参考,我们的databricks运行时环境是Scala 2.11)


谢谢。

问题应该来自行对象如何对键/字段进行排序,来自:

Row可用于通过使用命名参数创建Row对象,字段将按名称排序

myschema\u xb
中,这三列的定义顺序为
[\u xmlns,\u Version,myid]
。使用键定义myRow时:
(\u xmlns,\u Version,myid)
,实际生成的Row对象将是:

Row(MyIds=[Row(_ID='XY', _ID_Context='Exxwhy', _Type=9), Row(_ID='9152', _ID_Context='LNUMB', _Type=21)], _Version=12.3, _xmlns='http://some.where.com')
它将
myid
移动到第一列,这与模式不匹配,因此产生错误。当您使用小写列名
myid
时,行对象中的键被排序为
[''u Version'、''u xmlns'、'myid']
,其在右列中有
myid
,但
\u Version
\u xmls
已切换。这不会产生错误,因为简单数据类型可以通过类型转换,但生成的数据帧不正确

要解决此问题,您应该设置一个类似行的类并自定义键的顺序,以确保字段的顺序与架构中显示的顺序完全匹配:

from pyspark.sql import Row

MyOuterROW = Row('_xmlns', '_Version', 'MyIds')
MyInnerRow = Row('_ID', '_ID_Context', '_Type')

myRow = MyOuterROW( 
    "http://some.where.com", 
    12.3, 
    [ 
        MyInnerROW("XY", "Exxwhy", 9), 
        MyInnerROW("9152", "LNUMB", 21) 
    ] 
)              
print(myRow)
#Row(_xmlns='http://some.where.com', _Version=12.3, MyIds=[Row(_ID='XY', _ID_Context='Exxwhy', _Type=9), Row(_ID='9152', _ID_Context='LNUMB', _Type=21)])

rdf = spark.createDataFrame([myRow], schema=myschema_xb)