Pyspark 将SQL架构分配给Spark DataFrame

Pyspark 将SQL架构分配给Spark DataFrame,pyspark,apache-spark-sql,Pyspark,Apache Spark Sql,我正在将我的团队遗留的红移SQL代码转换为Spark SQL代码。我看到的所有Spark示例都使用StructType和StructField以非SQL方式定义模式,我更喜欢用SQL定义模式,因为我的大多数用户都知道SQL,但不知道Spark 这是我现在正在做的丑陋的变通方法。有没有一种更优雅的方法,不需要定义空表就可以提取SQL模式 create_table_sql = ''' CREATE TABLE public.example ( id LONG, example VARCHAR

我正在将我的团队遗留的红移SQL代码转换为Spark SQL代码。我看到的所有Spark示例都使用StructType和StructField以非SQL方式定义模式,我更喜欢用SQL定义模式,因为我的大多数用户都知道SQL,但不知道Spark

这是我现在正在做的丑陋的变通方法。有没有一种更优雅的方法,不需要定义空表就可以提取SQL模式

create_table_sql = '''
CREATE TABLE public.example (
  id LONG,
  example VARCHAR(80)
)'''
spark.sql(create_table_sql)
schema = spark.sql("DESCRIBE public.example").collect()
s3_data = spark.read.\
option("delimiter", "|")\
.csv(
    path="s3a://"+s3_bucket_path,
    schema=schema
)\
.saveAsTable('public.example')

是的,有一种方法可以从字符串创建模式,尽管我不确定它是否真的像SQL!因此,您可以使用:

from pyspark.sql.types import _parse_datatype_string

_parse_datatype_string("id: long, example: string")
这将创建下一个架构:

  StructType(List(StructField(id,LongType,true),StructField(example,StringType,true)))
或者您也可能有一个复杂的模式:

schema = _parse_datatype_string("customers array<struct<id: long, name: string, address: string>>")

StructType(
  List(StructField(
    customers,ArrayType(
      StructType(
        List(
          StructField(id,LongType,true),
          StructField(name,StringType,true),
          StructField(address,StringType,true)
        )
      ),true),true)
  )
)

您可以查看更多示例

为什么不能创建表public.new作为select*from public.example其中1=0?我不确定你在问什么。@pault因为S3中的源数据csv也不会将数据类型与值一起持久化。我怀疑Spark可以推断出一些类型,但我的一些列是小数,我需要以高精度跟踪,所以我想明确列的定义方式。