O Amazon Redshift não permitirá mais a criação de UDFs do Python a partir do Patch 198. As UDFs do Python existentes continuarão a funcionar normalmente até 30 de junho de 2026. Para ter mais informações, consulte a publicação de blog
Tipos de dados compatíveis
Os seguintes tipos de dados no Amazon Redshift são compatíveis com o conector do Spark. Para obter uma lista completa dos tipos de dados compatíveis no Amazon Redshift, consulte Tipos de dados. Se um tipo de dado não está na tabela abaixo, ele não é compatível com o conector do Spark.
| Tipo de dados | Aliases |
|---|---|
| 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 | Time stamp sem fuso horário |
| TIMESTAMPTZ | Time stamp com fuso horário |
| SUPER | |
| TIME | Hora sem fuso horário |
| TIMETZ | Hora com fuso horário |
| VARBYTE | VARBINARY, BINARY VARYING |
Tipos de dados complexos
É possível usar o conector Spark para ler e gravar tipos de dados complexos do Spark, como ArrayType, MapType e StructType de e para as colunas do tipo de dados SUPER do Redshift. Se você fornecer um esquema durante uma operação de leitura, os dados na coluna serão convertidos em seus tipos complexos correspondentes no Spark, incluindo qualquer tipo aninhado. Além disso, se autopushdown estiver habilitado, a projeção de atributos aninhados, valores de mapas e índices de matriz será enviada ao Redshift para que toda a estrutura de dados aninhada não precise mais ser descarregada ao acessar apenas uma parte dos dados.
Quando você grava DataFrames pelo conector, qualquer coluna do tipo MapType(usando StringType) StructType ou ArrayType é gravada em uma coluna de tipo de dados SUPER do Redshift. Ao escrever essas estruturas de dados aninhadas, o parâmetro tempformat deve ser do tipo CSV, CSV GZIP ou PARQUET. Usar AVRO causará uma exceção. Gravar uma estrutura de dados MapType que tem um tipo de chave diferente de StringType também causará uma exceção.
StructType
O exemplo a seguir demonstra como criar uma tabela com um tipo de dados SUPER que contém uma estrutura.
create table contains_super (a super);
Depois, é possível usar o conector para consultar um campo StringType hello da coluna a de SUPER na tabela usando um esquema como no exemplo a seguir.
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")
O exemplo a seguir demonstra como escrever uma estrutura na coluna 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
Se você preferir usar um MapType para representar seus dados, poderá usar uma estrutura de dados MapType no esquema e recuperar o valor correspondente a uma chave no mapa. Observe que todas as chaves na estrutura de dados MapType deve ser do tipo String e todos os valores devem ser do mesmo tipo, como int.
O exemplo a seguir demonstra como obter o valor da chave hello na coluna a.
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
Se a coluna contiver uma matriz em vez de uma estrutura, você poderá usar o conector para consultar o primeiro elemento na matriz.
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]")
Limitações
O uso de tipos de dados complexos com o conector do Spark tem as seguintes limitações:
-
Todos os nomes de campos de estrutura aninhados e chaves de mapa devem estar em letras minúsculas. Se estiver consultando nomes de campos complexos com letras maiúsculas, uma solução alternativa é tentar omitir o esquema e usar a função
from_jsondo Spark para converter a string retornada localmente. -
Qualquer campo de mapa usado em operações de leitura ou gravação precisa ter apenas chaves
StringType. -
Somente
CSV,CSV GZIPePARQUETsão valores de formato temporário compatíveis para gravar tipos complexos no Redshift. Tentar usarAVROlançará uma exceção.