我正在使用AWS S3,Glue和Athena进行以下设置:
S3 - >胶水 - >雅典娜
我的原始数据作为CSV文件存储在S3上。我正在使用Glue进行ETL,而我正在使用Athena来查询数据。
由于我使用的是Athena,我想将CSV文件转换为Parquet。我正在使用AWS Glue立即执行此操作。这是我正在使用的当前流程:
Glue作业只允许我一次转换一个表。如果我有许多CSV文件,这个过程很快就会变得无法管理。有没有更好的方法,也许是一种“正确”的方式,使用AWS Glue或其他一些AWS服务将许多 CSV文件转换为Parquet?
答案 0 :(得分:4)
在完全相同的情况下,我想有效地循环通过搜寻器分类的目录表,这些目录表指向csv文件,然后将它们转换为镶木地板。不幸的是,网络上尚无可用信息。这就是为什么我在LinkedIn中写了一个博客来解释我是如何做到的。请阅读;特别是第5点。希望能有所帮助。请让我知道您的反馈。
注意:根据Antti的反馈,我将粘贴以下博客摘录的解决方案:
“作业向导”带有用于在数据源上运行预定义脚本的选项。问题是您可以选择的数据源是目录中的单个表。它没有让您选择在整个数据库或一组表上运行作业。您仍然可以稍后修改脚本,但是在胶粘目录中遍历数据库表的方式也很难找到。有目录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()