지원되는 데이터 형식 - Amazon Redshift

지원되는 데이터 형식

Amazon Redshift의 다음 데이터 형식은 Spark 커넥터에서 지원됩니다. 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 커넥터를 사용하여 ArrayType, MapType, StructType과 같은 Spark 복합 데이터 형식을 Redshift SUPER 데이터 형식 열에 읽고 쓸 수 있습니다. 읽기 작업 중에 스키마를 제공하는 경우 열의 데이터는 중첩된 형식을 포함하여 Spark에서 해당 복합 형식으로 변환됩니다 또한 autopushdown을 활성화하면 중첩된 속성, 맵 값 및 배열 인덱스의 투영이 Redshift로 푸시다운되므로 데이터의 일부만 액세스할 때 중첩된 전체 데이터 구조를 더 이상 언로드할 필요가 없습니다.

커넥터에서 데이터 프레임을 작성할 때 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와 같은 동일한 형식이어야 한다는 점에 유의합니다.

다음 예는 열 hello에서 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_json spark 함수를 사용하여 반환된 문자열을 로컬로 변환하는 해결 방법을 시도해 볼 수 있습니다.

  • 읽기 또는 쓰기 작업에 사용되는 모든 맵 필드에는 StringType 키만 있어야 합니다.

  • 복잡한 형식을 Redshift에 쓰기 위한 임시 형식 값은 CSV, CSV GZIPPARQUET 만 지원됩니다. AVRO 를 사용하려고 하면 예외가 발생합니다.