2017-10-16 6 views
1

AWS S3에 AWS Glue에로드되는 CSV 파일이 있습니다. S3에서 소스 데이터 파일에 변환을 적용하는 데 사용됩니다. PySpark 스크립팅 환경을 제공합니다. 데이터는 다음과 같이 다소 같습니다 알파벳을 포함 할 수 있습니다 내가 형 정수의 이름 'PRIME_KEY'에 의해 현장에서 일하고 있어요 여기 SQL 쿼리를 통해 열의 숫자 값에 알파벳이 포함되어 있는지 확인하는 방법

"123","IND","25632349","112322abcd","2017-10-17"  
"123","IND","25635234","11243kjsd434","2017-10-17" 

가 어떤 결과 :

"ID","CNTRY_CD","SUB_ID","PRIME_KEY","DATE"  
"123","IND","25635525","11243749772","2017-10-17"  
"123","IND","25632349","112322abcd","2017-10-17"  
"123","IND","25635234","11243kjsd434","2017-10-17"  
"123","IND","25639822","1124374343","2017-10-17" 

예상 결과는 다음과 같이해야한다 잘못된 데이터 형식입니다.

이제 Integer 유형의 기본 키 열에 SQL 쿼리를 사용하는 숫자 값 대신 영숫자 문자가 포함되어 있는지 확인해야합니다.

SELECT * 
FROM table_name 
WHERE column_name IS NOT NULL AND 
CAST(column_name AS VARCHAR(100)) LIKE \'%[0-9a-z0-9]%\' 

소스 스크립트 :

args = getResolvedOptions(sys.argv, ['JOB_NAME']) 
glueContext = GlueContext(SparkContext.getOrCreate()) 
spark = glueContext.spark_session 
job = Job(glueContext) 
job.init(args['JOB_NAME'], args) 
# s3 output directory 
output_dir = "s3://aws-glue-scripts../.." 

# Data Catalog: database and table name 
db_name = "sampledb" 
glue_tbl_name = "sampleTable" 

datasource = glueContext.create_dynamic_frame.from_catalog(database = db_name, table_name = glue_tbl_name) 
datasource_df = datasource.toDF() 
datasource_df.registerTempTable("sample_tbl") 
invalid_primarykey_values_df = spark.sql("SELECT * FROM sample_tbl WHERE CAST(PRIME_KEY AS STRING) RLIKE '([a-z]+[0-9]+)|([0-9]+[a-z]+)'") 
invalid_primarykey_values_df.show() 

이 스크립트의 출력은 아래와 같습니다 : 정규 표현식 지금까지 내가 시도 약간의 변형은 아래와하지만 행운처럼이 작업을 수행하는

+ --- + -------- + -------- + ------------ + ---------- + ----------- + --------------- +

| ID | CNTRY_CD | SUB_ID | PRIME_KEY | DATE |

+ --- + -------- + -------- + ------------ + ---------- + ----------- + --------------- +

| 123 | IND | 25635525 | [11243749772, null] | 2017-10-17 |

| 123 | IND | 25632349 | [null, 112322ab .. | 2017-10-17 |

| 123 | IND | 25635234 | [null, 11243kjsd .. | 2017-10-17 |

| 123 | IND | 25639822 | [1124374343, null] | 2017-10-17 |

+ -------- + -------- + -------------------- + ------ ---- + ----------- + --------------- +

나는 작업중인 필드의 값을 강조 표시했습니다. . 소스 데이터와 다소 차이가 있습니다.

이 문제에 대한 도움을 주시면 대단히 감사하겠습니다. 감사합니다

답변

1

당신은 RLIKE

SELECT * 
FROM table_name 
WHERE CAST(PRIME_KEY AS STRING) RLIKE '([0-9]+[a-z]+)' 

더 일반적인 알파 숫자 필터 일치를 사용할 수 있습니다.

WHERE CAST(PRIME_KEY AS STRING) RLIKE '([a-z]+[0-9]+)|([0-9]+[a-z]+)' 

편집 : 코멘트에 따라

필요한 수입과 UDFS

val spark = SparkSession.builder 
    .config(conf) 
    .getOrCreate 

import org.apache.spark.sql.functions._ 
val extract_pkey = udf((x: String) => x.replaceAll("null|\\]|\\[|,", "").trim) 

import spark.implicits._ 

테스트를위한 샘플 데이터를 설정하고

val df = Seq(
    ("123", "IND", "25635525", "[11243749772,null]", "2017-10-17"), 
    ("123", "IND", "25632349", "[null,112322abcd]", "2017-10-17"), 
    ("123", "IND", "25635234", "[null,11243kjsd434]", "2017-10-17"), 
    ("123", "IND", "25639822", "[1124374343,null]", "2017-10-17") 
).toDF("ID", "CNTRY_CD", "SUB_ID", "PRIME_KEY", "DATE") 
    .withColumn("PRIME_KEY", extract_pkey($"PRIME_KEY")) 


df.registerTempTable("tbl") 

spark.sql("SELECT * FROM tbl WHERE PRIME_KEY RLIKE '([a-z]+[0-9]+)|([0-9]+[a-z]+)'") 
    .show(false) 

+---+--------+--------+------------+----------+ 
|ID |CNTRY_CD|SUB_ID |PRIME_KEY |DATE  | 
+---+--------+--------+------------+----------+ 
|123|IND  |25632349|112322abcd |2017-10-17| 
|123|IND  |25635234|11243kjsd434|2017-10-17| 
+---+--------+--------+------------+----------+ 
UDF

와 청소