【问题标题】:How to import referenced files in ETL scripts?如何在 ETL 脚本中导入引用文件?
【发布时间】:2022-03-11 17:39:55
【问题描述】:

我有一个脚本,我想将配置文件传递到其中。在 Glue 作业页面上,我看到有一个“引用文件路径”指向我的配置文件。然后如何在我的 ETL 脚本中使用该文件?

我试过from configuration import *,其中引用的文件名是configuration.py,但没有运气(ImportError: No module named configuration)。

【问题讨论】:

  • 我还没有找到一种可以按照胶水可能想要的方式进行集成的方法,但是目前使用sc.addPyFile('s3://bucket/path/to/file.py') 对我来说效果很好。

标签: pyspark aws-glue


【解决方案1】:

我注意到了同样的问题。我相信已经有一张票可以解决这个问题,但这就是 AWS 支持在此期间提出的建议。

如果您在 Python 中使用 引用文件路径 变量 shell 作业,引用文件在/tmp,其中Python shell job 默认没有访问权限。但是,相同的操作有效 在 Spark 作业中成功,因为该文件在默认情况下找到 文件目录。

下面的代码有助于找到在 Glue 作业配置中引用的 sample_config.json 的绝对路径并打印其内容。

import json
import sys, os

def get_referenced_filepath(file_name, matchFunc=os.path.isfile):
    for dir_name in sys.path:
        candidate = os.path.join(dir_name, file_name)
        if matchFunc(candidate):
            return candidate
    raise Exception("Can't find file: ".format(file_name))

with open(get_referenced_filepath('sample_config.json'), "r") as f:
    data = json.load(f)
    print(data)

Boto3 API 也可用于访问引用的文件

import boto3

s3 = boto3.resource('s3')
obj = s3.Object('sample_bucket', 'sample_config.json')
for line in obj.get()['Body']._raw_stream:
    print(line)

【讨论】:

    【解决方案2】:

    我在 Glue v2 Spark 作业中遇到了这个问题,而不是另一个答案详细讨论的 Python shell 作业。

    AWS 文档说没有必要压缩单个 .py 文件。不过,我还是决定使用.zip 文件。

    我的.zip 文件包含以下内容:

    Archive:  utils.zip
     Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
    --------  ------  ------- ---- ---------- ----- --------  ----
           0  Defl:N        5   0% 01-01-2049 00:00 00000000  __init__.py
        6603  Defl:N     1676  75% 01-01-2049 00:00 f4551ccb  utils.py
    --------          -------  ---                            -------
        6603             1681  75%                            2 files
    

    请注意,__init__.py 存在,并且使用 Deflate(通常的 zip 格式)压缩存档。

    在我的 Glue 作业中,我添加了 referenced files path 作业参数,指向我在 S3 上的 zip 文件。

    在作业脚本中,我需要将我的 zip 文件显式添加到 Python 路径中,然后才能进行导入。

    import sys
    sys.path.insert(0, "utils.zip")
    
    import utils
    

    未能执行上述操作会导致ImportError: No module named 错误。

    对于其他为此苦苦挣扎的人,检查以下变量有助于我调试问题并得出解决方案。粘贴到您的 Glue 作业并在 Cloudwatch 中查看结果。

    import sys
    import os
    
    print(f"os.getcwd()={os.getcwd()}")
    print(f"os.listdir('.')={os.listdir('.')}")
    print(f"sys.path={sys.path}")
    

    【讨论】:

      猜你喜欢
      • 2023-02-25
      • 1970-01-01
      • 2018-07-20
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      相关资源
      最近更新 更多