【问题标题】:Read lines between ranges from s3 file从 s3 文件中读取范围之间的行
【发布时间】:2020-09-25 00:06:51
【问题描述】:

我在 aws-s3 存储桶中有一个 s3 csv 文件。我只想读取文件中的行范围,而不是整个文件。

我的目标是,以表格形式在 UI 应用程序中以分页方式获取文件内容。

我从这个link 读到Range 选项存在于s3.getObject 中。

但我不需要字节范围,但我需要行范围。例如:(1-100,类似于分页)

有没有一种方法可以使用 NodeJS 做到这一点?

【问题讨论】:

  • 不,S3 不支持行范围。
  • 是的,我同意 S3 不直接支持它。但是有间接的方法吗?类似的东西 - stackoverflow.com/a/39745836/2173020
  • 原因是,文件大小难以想象,我不想加载所有内容。所以寻找一些替代方案
  • 您尝试过 Amazon S3 Select 吗?它支持CSV文件。
  • 没问题。这是一个写得很好的blog post 开始。

标签: node.js amazon-web-services amazon-s3


【解决方案1】:

您可以使用 S3 select(添加新列 row_index 以限制行数)或 Athena 来查询 CSV 文件。

S3 选择程序从 CSV 文件中打印 1000 行

import boto3
S3_BUCKET = 'bucket-name'

s3 = boto3.client('s3')

r = s3.select_object_content(
        Bucket=S3_BUCKET,
        Key='filename.csv',
        ExpressionType='SQL',
        Expression="select \"column\" from s3object s where row_index >= 1 and row_index <= 1000,
        InputSerialization={'CSV': {"FileHeaderInfo": "Use"}},
        OutputSerialization={'CSV': {}},
)

for event in r['Payload']:
    if 'Records' in event:
        records = event['Records']['Payload'].decode('utf-8')
        print(records)

使用雅典娜

您只需在 Athena 中上传 CSV 文件即可。将文件上传到 Athena 非常简单。然后您可以从选择查询中查询有限的数据集。

SELECT * FROM table limit 1000;

【讨论】:

    【解决方案2】:

    目前没有 s3 不支持这个。

    您必须提取整个文件,然后您可以使用 fast-csv 模块对其进行过滤。

    您可以使用该模块的skip-rows和max-rows来形成一个范围。

    https://c2fo.io/fast-csv/docs/parsing/options

    【讨论】:

      【解决方案3】:

      S3 select_object_content 不支持 row_number() 函数。如果您的 CSV 中有任何唯一/范围列,请使用该列执行选择查询以获取特定范围的行/行。但永远不要忘记在查询中将范围列转换为整数,否则它将被视为字符串。

      import boto3
      S3_BUCKET = 'bucket-name'
      
      s3 = boto3.client('s3')
      
      r = s3.select_object_content(
              Bucket=S3_BUCKET,
              Key='filename.csv',
              ExpressionType='SQL',
              Expression="select * from s3object s where CAST(row_index as INT) >= 1 and CAST(row_index as INT) <= 100",
              InputSerialization={'CSV': {"FileHeaderInfo": "Use"}},
              OutputSerialization={'CSV': {}},
      )
      
      for event in r['Payload']:
          if 'Records' in event:
              records = event['Records']['Payload'].decode('utf-8')
              print(records)
      

      【讨论】:

        【解决方案4】:

        您可以将您的行转换为它们各自的字节。有一个 npm 模块可以转换为字节

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-19
          • 1970-01-01
          • 2012-06-24
          • 2016-10-10
          • 2022-12-20
          • 1970-01-01
          • 2017-02-13
          • 1970-01-01
          相关资源
          最近更新 更多