Amazon Redshift dejará de admitir la creación de nuevas UDF de Python a partir del parche 198. Las UDF de Python existentes seguirán funcionando hasta el 30 de junio de 2026. Para obtener más información, consulte la publicación del blog
Tipos de datos compatibles
Los siguientes tipos de datos de Amazon Redshift son compatibles con el conector de Spark. Para obtener una lista completa de los tipos de datos compatibles con Amazon Redshift, consulte Data types (Tipos de datos). Si un tipo de datos no se encuentra en la tabla siguiente, no está admitido en el conector de Spark.
| Tipo de datos: | Alias |
|---|---|
| SMALLINT | INT2 |
| INTEGER | INT, INT4 |
| BIGINT | INT8 |
| DECIMAL | NUMERIC |
| REAL | FLOAT4 |
| DOUBLE PRECISION | FLOAT8, FLOAT |
| BOOLEANO | BOOL |
| CHAR | CHARACTER, NCHAR, BPCHAR |
| VARCHAR | CHARACTER VARYING, NVARCHAR, TEXT |
| DATE | |
| TIMESTAMP | TIMESTAMP sin zona horaria |
| TIMESTAMPTZ | Timestamp with time zone |
| SUPER | |
| TIME | Hora sin zona horaria |
| TIMETZ | Time with time zone |
| VARBYTE | VARBINARY, BINARY VARYING |
Tipos de datos complejos
Puede usar el conector Spark para leer y escribir tipos de datos complejos de Spark, como ArrayType, MapType y StructType hacia y desde las columnas de tipos de datos SUPER de Redshift. Si proporciona un esquema durante una operación de lectura, los datos de la columna se convertirán en los tipos complejos correspondientes en Spark, incluidos los tipos anidados. Además, si autopushdown está habilitado, la proyección de los atributos anidados, los valores del mapa y los índices de matriz se reducen a Redshift, de modo que ya no es necesario descargar toda la estructura de datos anidada al acceder solo a una parte de los datos.
Cuando escribe DataFrames desde el conector, cualquier columna de tipo MapType (con StringType), StructType o ArrayType se escribe en una columna de tipos de datos SUPER de Redshift. Al escribir estas estructuras de datos anidadas, el parámetro tempformat debe ser del tipo CSV, CSV GZIP o PARQUET. Con AVRO provocará una excepción. La escritura de una estructura de datos MapType que tiene un tipo de clave distinto de StringType también provocará una excepción.
StructType
En el siguiente ejemplo se muestra cómo crear una tabla con un tipo de datos SUPER que contiene una estructura
create table contains_super (a super);
A continuación, puede utilizar el conector para consultar un campo StringType hello de la columna SUPER a en la tabla utilizando un esquema como el del siguiente ejemplo.
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")
En el siguiente ejemplo se muestra cómo se escribe una estructura en la columna 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
Si prefiere usar MapType para representar los datos, puede usar una estructura de datos MapType en el esquema y recupera el valor correspondiente a una clave en el mapa. Tenga en cuenta que todas las claves de la estructura de datos MapType debe ser de tipo String y todos los valores deben ser del mismo tipo, como int.
En el siguiente ejemplo se muestra cómo obtener el valor de la clave hello en la columna 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
Si la columna contiene una matriz en lugar de una estructura, puede usar el conector para consultar el primer elemento de la 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]")
Limitaciones
Con los tipos de datos complejos con el conector de Spark se presentan las siguientes limitaciones:
-
Todos los nombres de los campos de estructura anidados y las claves de mapa deben estar en minúsculas. Si busca nombres de campos complejos con letras mayúsculas, puede intentar omitir el esquema y usar la función de Spark
from_jsonpara convertir la cadena devuelta localmente como una solución alternativa. -
Todos los campos del mapa utilizados en las operaciones de lectura o escritura deben tener solo claves
StringType. -
Solo
CSV,CSV GZIPyPARQUETson valores de formato temporal compatibles para escribir tipos complejos en Redshift. Al intentar usarAVROse generará una excepción.