Amazon Redshift 將不再支援從修補程式 198 開始建立新的 Python UDFs。現有 Python UDF 將繼續正常運作至 2026 年 6 月 30 日。如需詳細資訊,請參閱部落格文章
本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
支援的資料類型
Spark 連接器支援 Amazon Redshift 中的下列資料類型。如需 Amazon Redshift 中支援的資料類型完整清單,請參閱資料類型。如果資料類型不在下表中,則表示 Spark 連接器不支援該資料類型。
| 資料類型 | 別名 |
|---|---|
| SMALLINT | INT2 |
| INTEGER | INT、INT4 |
| BIGINT | INT8 |
| DECIMAL | NUMERIC |
| REAL | FLOAT4 |
| DOUBLE PRECISION | FLOAT8、FLOAT |
| BOOLEAN | BOOL |
| CHAR | CHARACTER、NCHAR、BPCHAR |
| VARCHAR | CHARACTER VARYING、NVARCHAR、TEXT |
| DATE | |
| TIMESTAMP | 不含時區的時間戳記 |
| TIMESTAMPTZ | 含時區的時間戳記 |
| SUPER | |
| TIME | 不含時區的時間 |
| TIMETZ | 含時區的時間 |
| VARBYTE | VARBINARY、BINARY VARYING |
複雜資料類型
您可以使用 Spark 連接器在 Redshift SUPER 資料類型資料欄中讀取和寫入 Spark 複雜資料類型 (例如 ArrayType、MapType 和 StructType)。如果您在讀取操作期間提供結構描述,資料欄中的資料會轉換為其在 Spark 中對應的複雜類型,包括任何巢狀類型。此外,如果已啟用 autopushdown,則巢狀屬性、映射值和陣列索引的投影會向下推送至 Redshift,在只存取一部分資料時,就不再需要卸載整個巢狀資料結構。
當您從連接器寫入 DataFrames 時,任何類型為 MapType (使用StringType)、StructType、或 ArrayType 的資料欄都會寫入到 Redshift SUPER 資料類型資料欄。在撰寫這些巢狀資料結構時,tempformat 參數的類型必須是 CSV、CSV GZIP 或 PARQUET。使用 AVRO 會導致例外狀況。撰寫具有 StringType 以外索引鍵類型的 MapType 資料結構也會導致例外狀況。
StructType
下列範例會示範如何建立具有 SUPER 資料類型且包含以下結構的資料表
create table contains_super (a super);
然後,您可以使用連接器,在使用如下列範例中的結構描述的資料表中,從 SUPER 資料欄 a 查詢 StringType 欄位 hello。
import org.apache.spark.sql.types._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", StructType(StructField("hello", StringType) ::Nil)) :: Nil) val helloDF = sqlContext.read .format("io.github.spark_redshift_community.spark.redshift") .option("url", jdbcURL ) .option("tempdir", tempS3Dir) .option("dbtable", "contains_super") .schema(schema) .load().selectExpr("a.hello")
下列範例會示範如何將結構寫入到資料欄 a。
import org.apache.spark.sql.types._ import org.apache.spark.sql._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", StructType(StructField("hello", StringType) ::Nil)) :: Nil) val data = sc.parallelize(Seq(Row(Row("world")))) val mydf = sqlContext.createDataFrame(data, schema) mydf.write.format("io.github.spark_redshift_community.spark.redshift"). option("url", jdbcUrl). option("dbtable", tableName). option("tempdir", tempS3Dir). option("tempformat", "CSV"). mode(SaveMode.Append).save
MapType
如果您偏好使用 MapType 來表示資料,則可以在結構描述中使用 MapType 資料結構,並擷取映射中與索引鍵對應的值。請注意,MapType 資料結構中的所有索引鍵都必須是字串類型,並且所有值都必須是相同類型,例如 int。
下列範例會示範如何取得資料欄 a 中索引鍵 hello 的值。
import org.apache.spark.sql.types._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", MapType(StringType, IntegerType))::Nil) val helloDF = sqlContext.read .format("io.github.spark_redshift_community.spark.redshift") .option("url", jdbcURL ) .option("tempdir", tempS3Dir) .option("dbtable", "contains_super") .schema(schema) .load().selectExpr("a['hello']")
ArrayType
如果資料欄包含陣列而不是結構,您可以使用連接器來查詢陣列中的第一個元素。
import org.apache.spark.sql.types._ val sc = // existing SparkContext val sqlContext = new SQLContext(sc) val schema = StructType(StructField("a", ArrayType(IntegerType)):: Nil) val helloDF = sqlContext.read .format("io.github.spark_redshift_community.spark.redshift") .option("url", jdbcURL ) .option("tempdir", tempS3Dir) .option("dbtable", "contains_super") .schema(schema) .load().selectExpr("a[0]")
限制
搭配 Spark 連接器使用複雜資料類型時有下列限制:
-
所有巢狀的結構欄位名稱和映射索引鍵都必須小寫。如果要查詢包含大寫字母的複雜欄位名稱,因應措施是您可以嘗試省略結構描述,並使用
from_jsonSpark 函數在本機轉換傳回的字串。 -
讀取或寫入操作中使用的任何映射欄位都必須只有
StringType索引鍵。 -
只有
CSV、CSV GZIP和PARQUET才是支援將複雜類型寫入到 Redshift 的 tempformat 值。嘗試使用AVRO會擲回例外狀況。