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 |
BOOLEAN | 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_json
para 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 GZIP
yPARQUET
son valores de formato temporal compatibles para escribir tipos complejos en Redshift. Al intentar usarAVRO
se generará una excepción.