如何使用AWS Glue将许多CSV文件转换为Parquet

时间:2018-04-23 16:54:04

标签: amazon-s3 parquet amazon-athena aws-glue

我正在使用AWS S3,Glue和Athena进行以下设置:

S3 - >胶水 - >雅典娜

我的原始数据作为CSV文件存储在S3上。我正在使用Glue进行ETL,而我正在使用Athena来查询数据。

由于我使用的是Athena,我想将CSV文件转换为Parquet。我正在使用AWS Glue立即执行此操作。这是我正在使用的当前流程:

  1. 运行Crawler以读取CSV文件并填充数据目录。
  2. 运行ETL作业以从数据目录创建Parquet文件。
  3. 运行Crawler以使用Parquet文件填充数据目录。
  4. Glue作业只允许我一次转换一个表。如果我有许多CSV文件,这个过程很快就会变得无法管理。有没有更好的方法,也许是一种“正确”的方式,使用AWS Glue或其他一些AWS服务将许多 CSV文件转换为Parquet?

5 个答案:

答案 0 :(得分:4)

在完全相同的情况下,我想有效地循环通过搜寻器分类的目录表,这些目录表指向csv文件,然后将它们转换为镶木地板。不幸的是,网络上尚无可用信息。这就是为什么我在LinkedIn中写了一个博客来解释我是如何做到的。请阅读;特别是第5点。希望能有所帮助。请让我知道您的反馈。

注意:根据Antti的反馈,我将粘贴以下博客摘录的解决方案:

  1. 遍历目录/数据库/表

“作业向导”带有用于在数据源上运行预定义脚本的选项。问题是您可以选择的数据源是目录中的单个表。它没有让您选择在整个数据库或一组表上运行作业。您仍然可以稍后修改脚本,但是在胶粘目录中遍历数据库表的方式也很难找到。有目录API,但缺少合适的示例。 github示例存储库中可以添加更多方案,以帮助开发人员。

经过一番摸索之后,我想到了下面的脚本来完成工作。我已使用boto3客户端遍历表。如果有人需要帮助,我会在这里粘贴。如果您有更好的建议,我也希望收到您的来信

import sys

import boto3

from awsglue.transforms import *

from awsglue.utils import getResolvedOptions

from pyspark.context import SparkContext

from awsglue.context import GlueContext

from awsglue.job import Job



## @params: [JOB_NAME]

args = getResolvedOptions(sys.argv, ['JOB_NAME'])



sc = SparkContext()

glueContext = GlueContext(sc)

spark = glueContext.spark_session

job = Job(glueContext)

job.init(args['JOB_NAME'], args)



client = boto3.client('glue',region_name='ap-southeast-2')



databaseName = 'tpc-ds-csv'

print '\ndatabaseName: ' + databaseName



Tables = client.get_tables( DatabaseName = databaseName )

tableList = Tables ['TableList']



for table in tableList:

   tableName = table['Name']

   print '\n-- tableName: '+tableName

   datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "tpc-ds-csv", table_name = tableName, transformation_ctx = "datasource0")

   datasink4 = glueContext.write_dynamic_frame.from_options(frame = datasource0, connection_type = "s3", connection_options = {"path": "s3://aws-glue-tpcds-parquet/"+ tableName + "/"}, format = "parquet", transformation_ctx = "datasink4")
job.commit()

答案 1 :(得分:2)

请参阅编辑以获取最新信息。

  

S3 - >雅典娜

为什么不直接使用Athena的CSV格式?

https://docs.aws.amazon.com/athena/latest/ug/supported-format.html

CSV是受支持的格式之一。另外,为了提高效率,您可以压缩多个CSV文件以加快加载速度。

支持压缩,

https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html

希望它有所帮助。

修改

为什么Parquet格式比CSV更有用?

https://dzone.com/articles/how-to-be-a-hero-with-powerful-parquet-google-and

  

S3 - >胶水 - >雅典娜

有关CSV到Parquet转换的更多详细信息,

https://aws.amazon.com/blogs/big-data/build-a-data-lake-foundation-with-aws-glue-and-amazon-s3/

答案 2 :(得分:1)

我不是Glue的忠实拥护者,也不是从数据创建模式

这是在雅典娜中做的方法,它比Glue快得多。

这是CSV文件:

create table foo (
  id int,
  name string,
  some date
)
row format delimited
  fields terminated by ','
location 's3://mybucket/path/to/csvs/'

这是用于实木复合地板文件的

create table bar 
with (
  external_location = 's3://mybucket/path/to/parquet/',
  format = 'PARQUET'
)
as select * from foo 

即使使用分区,也无需为镶木地板创建该路径

答案 3 :(得分:0)

听起来在步骤1中您正在抓取单个csv文件(例如some-bucket / container-path / file.csv),但是如果您改为将爬虫设置为查看路径级别而不是文件级别(例如some-bucket / container-path /)并且所有csv文件都是统一的,然后爬虫应该只为每个文件创建一个外部表而不是外部表,并且您将能够从所有文件中提取数据一次。

答案 4 :(得分:0)

您可以将JSON或CSV文件直接转换为实木复合地板,而无需先将其导入目录中。

这是用于JSON文件的代码-以下代码将转换rawFiles目录中托管的任何内容

import sys
from awsglue.job import Job 
from awsglue.transforms import *
from awsglue.context import GlueContext
from pyspark.context import SparkContext
from awsglue.utils import getResolvedOptions

## @params: [JOB_NAME] args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sparkContext = SparkContext()
glueContext = GlueContext(sparkContext)
spark = glueContext.spark_session
job = Job(glueContext) job.init(args['JOB_NAME'], args)

s3_json_path = 's3://rawFiles/'  
s3_parquet_path = 's3://convertedFiles/'

output = spark.read.load(s3_json_path, format='json') 
output.write.parquet(s3_parquet_path)

job.commit()