

# 在 AWS Glue 中为 Python shell 作业配置作业属性
<a name="add-job-python"></a>

 可以使用 Python shell 作业将 Python 脚本作为 AWS Glue 中的 shell 运行。利用 Python Shell 作业，您可以运行与 Python 3.6 或 Python 3.9 兼容的脚本。

**注意**  
 对 Pyshell v3.6 的支持将于 2026 年 3 月 1 日结束。要迁移工作负载，请参阅[从 AWS Glue Python Shell 作业迁移](https://docs.aws.amazon.com/glue/latest/dg/pyshell-migration.html)。如果想继续使用 Python shell v3.9，请参阅 [从 Python shell 3.6 迁移到 Python shell 3.9](#migrating-version-pyshell36-to-pyshell39)。

**Topics**
+ [限制](#python-shell-limitations)
+ [执行环境](#python-shell-execution-environment)
+ [定义 Python shell 作业的作业属性](#create-job-python-properties)
+ [适用于 Python shell 作业的支持的库](#python-shell-supported-library)
+ [提供您自己的 Python 库](#create-python-extra-library)
+ [将 AWS CloudFormation 与 AWS Glue 中的 Python Shell 作业一起使用](#python-shell-jobs-cloudformation)
+ [从 Python shell 3.6 迁移到 Python shell 3.9](#migrating-version-pyshell36-to-pyshell39)
+ [从 AWS Glue Python Shell 作业迁移](pyshell-migration.md)

## 限制
<a name="python-shell-limitations"></a>

请注意 Python Shell 作业的以下限制：
+  您不能将作业书签用于 Python shell 作业。
+ 在 Python 3.9\$1 版本中，不能将任何 Python 库打包成 `.egg` 文件。请改用`.whl`。
+ 由于 S3 数据的临时副本存在限制，因此无法使用 `--extra-files` 选项。

## 执行环境
<a name="python-shell-execution-environment"></a>

Python Shell 作业在托管式执行环境中运行，该环境为临时数据处理提供对本地存储的访问权限：

**本地临时存储**  
`/tmp` 目录可在作业执行期间临时存储。此目录提供了大约 14 GiB 的可用空间，可用于：  
+ 临时文件处理
+ 中间数据存储
+ 缓存小数据集
`/tmp` 目录是临时性的，将在作业完成后清理。请勿将其用于永久存储重要数据。

## 定义 Python shell 作业的作业属性
<a name="create-job-python-properties"></a>

以下各节介绍如何在 AWS Glue Studio 中或使用 AWS CLI 定义任务属性。

### AWS Glue Studio
<a name="create-job-python-properties-studio"></a>

当您在 AWS Glue Studio 中定义 Python shell 任务时，请提供以下一些属性：

**IAM 角色**  
指定用于对运行任务和访问数据存储所用的资源进行授权的 AWS Identity and Access Management（IAM）角色。有关在 AWS Glue 中运行作业的权限的更多信息，请参阅 [适用于 AWS Glue 的 Identity and Access Management](security-iam.md)。

**Type**  
选择 **Python shell** 命令以使用名为 `pythonshell` 的作业运行 Python 脚本。

**Python 版本**  
选择 Python 版本。默认为 Python 3.9。有效版本为 Python 3.6 和 Python 3.9。

**加载常用分析库（推荐）**  
选择此选项可在 Python shell 中包含适用于 Python 3.9 的常用库。  
如果您的库是自定义的或者与预安装的库冲突，则可以选择不安装常用库。但是，除了常用库之外，您还可以安装其他库。  
如果您选择此选项，则 `library-set` 选项设置为 `analytics`。如果您取消选择此选项，则 `library-set` 选项设置为 `none`。

**脚本文件名和脚本路径**  
脚本中的代码定义了作业的过程逻辑。您需要在 Amazon Simple Storage Service（Amazon S3）中提供脚本名称和位置。确认没有与路径中的脚本目录同名的文件。要了解有关使用脚本的更多信息，请参阅 [AWS Glue 编程指南](edit-script.md)。

**Script**  
脚本中的代码定义了作业的过程逻辑。您可以在 Python 3.6 或 Python 3.9 中编写脚本代码。您可以在 AWS Glue Studio 中编辑脚本。

**数据处理单元**  
此作业运行时可分配的 AWS Glue 数据处理单元 (DPU) 的最大数量。DPU 是对处理能力的相对度量，它由 4 个 vCPU 的计算容量和 16GB 内存组成。有关更多信息，请参阅[AWS Glue定价](https://aws.amazon.com/glue/pricing/)。  
您可以将该值设置为 0.0625 或 1。默认值为 0.0625。无论哪种情况，该实例的本地磁盘都将为 20GB。

### CLI
<a name="create-job-python-properties-cli"></a>

 您还可以使用 AWS CLI 创建 **Python Shell** 任务，如以下示例所示。

```
 aws glue create-job --name python-job-cli --role Glue_DefaultRole 
     --command '{"Name" :  "pythonshell", "PythonVersion": "3.9", "ScriptLocation" : "s3://amzn-s3-demo-bucket/scriptname.py"}'  
     --max-capacity 0.0625
```

**注意**  
 您无需指定 AWS Glue 的版本，因为参数 `--glue-version` 不适用于 AWS Glue Shell 作业。指定的任何版本都将被忽略。

 您使用 AWS CLI 创建的任务默认为 Python 3。有效的 Python 版本为 3（对应于 3.6）和 3.9。要指定 Python 3.6，请添加此元组到 `--command` 参数：`"PythonVersion":"3"`

 要指定 Python 3.9，请添加此元组到 `--command` 参数：`"PythonVersion":"3.9"`

 要设置 Python shell 作业使用的最大容量，请提供 `--max-capacity` 参数。对于 Python shell 作业，无法使用 `--allocated-capacity` 参数。

## 适用于 Python shell 作业的支持的库
<a name="python-shell-supported-library"></a>

 在使用 Python 3.9 的 Python shell 中，您可以选择库集来使用预先打包的库集来满足您的需求。您可以使用 `library-set` 选项选择库集。有效值为 `analytics` 和 `none`。

用于运行 Python shell 作业的环境支持以下库：


| Python 版本 | Python 3.6 | Python 3.9 | 
| --- | --- | --- | 
| 库集 | 不适用 | 分析 | none | 
| avro |  | 1.11.0 |  | 
| awscli | 116.242 | 1.23.5 | 1.23.5 | 
| awswrangler |  | 2.15.1 |  | 
| botocore | 1.12.232 | 1.24.21 | 1.23.5 | 
| boto3 | 1.9.203 | 1.21.21 |  | 
| elasticsearch |  | 8.2.0 |  | 
| numpy | 1.16.2 | 1.22.3 |  | 
| pandas | 0.24.2 | 1.4.2 |  | 
| psycopg2 |  | 2.9.3 |  | 
| pyathena |  | 2.5.3 |  | 
| PyGreSQL | 5.0.6 |  |  | 
| PyMySQL |  | 1.0.2 |  | 
| pyodbc |  | 4.0.32 |  | 
| pyorc |  | 0.6.0 |  | 
| redshift-connector |  | 2.0.907 |  | 
| 请求 | 2.22.0 | 2.27.1 |  | 
| scikit-learn | 0.20.3 | 1.0.2 |  | 
| scipy | 1.2.1 | 1.8.0 |  | 
| SQLAlchemy |  | 1.4.36 |  | 
| s3fs |  | 2022.3.0 |  | 

可以在 Python shell 作业中使用 `NumPy` 库以进行科学计算。有关更多信息，请参阅 [NumPy](http://www.numpy.org)。以下示例显示了一个可在 Python shell 作业中使用的 NumPy 脚本。该脚本输出“Hello world”和多个数学计算的结果。

```
import numpy as np
print("Hello world")

a = np.array([20,30,40,50])
print(a)

b = np.arange( 4 )

print(b)

c = a-b

print(c)

d = b**2

print(d)
```

## 提供您自己的 Python 库
<a name="create-python-extra-library"></a>

### 使用 PIP
<a name="create-python-extra-library-pip"></a>

使用 Python 3.9 的 Python shell 允许您在任务层面提供其他 Python 模块或不同版本。您可以结合使用 `--additional-python-modules` 选项与一系列逗号分隔的 Python 模块，以添加新模块或更改现有模块的版本。使用 Python Shell 作业时，您不能为托管在 Amazon S3 上的自定义 Python 模块提供此参数。

例如，要更新或添加新的 `scikit-learn` 模块，请使用以下键/值：`"--additional-python-modules", "scikit-learn==0.21.3"`。

AWS Glue 使用 Python Package Installer（pip3）来安装其他模块。您可以在 `--additional-python-modules` 值中传递额外的 pip3 选项。例如 `"scikit-learn==0.21.3 -i https://pypi.python.org/simple/"`。pip3 的任何不兼容或限制都将适用。

**注意**  
为避免将来出现不兼容性，我们建议使用为 Python 3.9 构建的库。

### 使用 Egg 或 Whl 文件
<a name="create-python-extra-library-egg-whl"></a>

您可能已将一个或多个 Python 库打包为一个 `.egg` 或 `.whl` 文件。如果是这样的话，您可以使用“`--extra-py-files`”标记下的 AWS Command Line Interface (AWS CLI) 将其指定到您的作业，如以下示例所示。

```
aws glue create-job --name python-redshift-test-cli --role role --command '{"Name" :  "pythonshell", "ScriptLocation" : "s3://MyBucket/python/library/redshift_test.py"}' 
     --connections Connections=connection-name --default-arguments '{"--extra-py-files" : ["s3://amzn-s3-demo-bucket/EGG-FILE", "s3://amzn-s3-demo-bucket/WHEEL-FILE"]}'
```

如果您不确定如何从 Python 库创建 `.egg` 或 `.whl` 文件，请使用以下步骤。此示例适用于 macOS、Linux 和 Windows Linux 子系统 (WSL)。

**创建 Python .egg 或 .whl 文件**

1. 在 Virtual Private Cloud（VPC）中创建 Amazon Redshift 集群，并且将一些数据添加到表。

1. 为您用于创建集群的 VPC-SecurityGroup-Subnet 组合创建 AWS Glue 连接。测试连接是否成功。

1. 创建一个名为 `redshift_example` 的目录，并且创建一个名为 `setup.py` 的文件。将以下代码粘贴到 `setup.py`。

   ```
   from setuptools import setup
   
   setup(
       name="redshift_module",
       version="0.1",
       packages=['redshift_module']
   )
   ```

1. 在 `redshift_example` 目录中，创建一个 `redshift_module` 目录。在 `redshift_module` 目录，创建文件 `__init__.py` 和 `pygresql_redshift_common.py`。

1. 将 `__init__.py` 文件留空。在 `pygresql_redshift_common.py` 中，粘贴以下代码。将 *port*、*db\$1name*、*user* 和 *password\$1for\$1user* 替换为特定于您的 Amazon Redshift 集群的详细信息。将 *table\$1name* 替换为 Amazon Redshift 中表的名称。

   ```
   import pg
   
   
   def get_connection(host):
       rs_conn_string = "host=%s port=%s dbname=%s user=%s password=%s" % (
           host, port, db_name, user, password_for_user)
   
       rs_conn = pg.connect(dbname=rs_conn_string)
       rs_conn.query("set statement_timeout = 1200000")
       return rs_conn
   
   
   def query(con):
       statement = "Select * from table_name;"
       res = con.query(statement)
       return res
   ```

1. 如果您尚未在此处，请切换到 `redshift_example` 目录。

1. 请执行以下操作之一：
   + 要创建 `.egg` 文件，请运行以下命令。

     ```
     python setup.py bdist_egg
     ```
   + 要创建 `.whl` 文件，请运行以下命令。

     ```
     python setup.py bdist_wheel
     ```

1. 安装上述命令中所需的依赖项。

1. 此命令会在 `dist` 目录中创建一个文件：
   + 如果您创建了一个 egg 文件，则此文件的名称为 `redshift_module-0.1-py2.7.egg`。
   + 如果您创建了一个 wheel 文件，则此文件的名称为 `redshift_module-0.1-py2.7-none-any.whl`。

   将此文件上载到 Amazon S3。

   在本例中，上传的文件路径是 *s3://amzn-s3-demo-bucket/EGG-FILE* 或 *s3://amzn-s3-demo-bucket/WHEEL-FILE*。

1. 创建一个要用作 AWS Glue 作业的脚本的 Python 文件，并将以下代码添加到该文件。

   ```
   from redshift_module import pygresql_redshift_common as rs_common
   
   con1 = rs_common.get_connection(redshift_endpoint)
   res = rs_common.query(con1)
   
   print "Rows in the table cities are: "
   
   print res
   ```

1. 将上述文件上载到 Amazon S3。在本例中，上传的文件路径是 *s3://amzn-s3-demo-bucket/scriptname.py*。

1. 使用此脚本创建一个 Python shell 作业。在 AWS Glue 控制台上，使用 **Job properties (任务属性)** 页面上的 **Python library path (Python 库路径)** 框指定 `.egg/.whl` 文件的路径。如果您有多个 `.egg/.whl` 文件和 Python 文件，请在此框中提供逗号分隔的列表。

   修改或重命名 `.egg` 文件时，文件名必须使用由“python setup.py bdist\$1egg”命令生成的默认名称，或者必须遵守 Python 模块命名约定。有关更多信息，请参阅 [Python 代码风格指南](https://www.python.org/dev/peps/pep-0008/)。

   借助 AWS CLI，使用命令创建作业，如以下示例中所示。

   ```
   aws glue create-job --name python-redshift-test-cli --role Role --command '{"Name" :  "pythonshell", "ScriptLocation" : "s3://amzn-s3-demo-bucket/scriptname.py"}' 
        --connections Connections="connection-name" --default-arguments '{"--extra-py-files" : ["s3://amzn-s3-demo-bucket/EGG-FILE", "s3://amzn-s3-demo-bucket/WHEEL-FILE"]}'
   ```

   任务运行时，脚本会打印在 Amazon Redshift 集群的 *table\$1name* 表中创建的行。

## 将 AWS CloudFormation 与 AWS Glue 中的 Python Shell 作业一起使用
<a name="python-shell-jobs-cloudformation"></a>

 您可以将 AWS CloudFormation 与 AWS Glue 中的 Python Shell 作业一起使用。以下是示例：

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Python39Job:
    Type: 'AWS::Glue::Job'
    Properties:
      Command:
        Name: pythonshell
        PythonVersion: '3.9'
        ScriptLocation: 's3://bucket/location'
      MaxRetries: 0
      Name: python-39-job
      Role: RoleName
```

 用于 Amazon CloudWatch Logs 组的 Python shell 任务输出为 `/aws-glue/python-jobs/output`。有关错误，请参阅日志组 `/aws-glue/python-jobs/error`。

## 从 Python shell 3.6 迁移到 Python shell 3.9
<a name="migrating-version-pyshell36-to-pyshell39"></a>

 要将 Python shell 作业迁移到最新 AWS Glue 版本，请执行以下操作：

1.  在 AWS Glue 控制台（[https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)）中，选择现有的 Python shell 作业。

1.  在**作业**详细信息选项卡中，将 Python 版本设置为 `Python 3.9`，然后选择**保存**。

1.  确保自己的作业脚本与 Python 3.9 兼容，并且能够成功运行。