搭配 Glue 使用 Python AWS 程式庫 - AWS Glue

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

搭配 Glue 使用 Python AWS 程式庫

您可以安裝其他 Python 模組和程式庫,以與 Glue ETL AWS 搭配使用。對於 AWS Glue 2.0 及更高版本, AWS Glue 使用 Python 套件安裝程式 (pip3) 來安裝 AWS Glue ETL 使用的其他模組。 AWS Glue 提供多種選項,可將其他 Python 模組帶入您的 AWS Glue 任務環境。您可以使用「–additional-python-modules」參數,使用 Python wheel 檔案、需求檔案 (requirement.txt、 AWS Glue 5.0 及更高版本) 或逗號分隔的 Python 模組清單來引入模組。

AWS 共同責任模型下,您負責管理與 Glue ETL 任務搭配使用的其他 Python AWS 模組、程式庫及其相依性。這包括套用更新和安全性修補程式。

AWS Glue 不支援在任務環境中編譯原生程式碼。不過, AWS Glue 任務會在 Amazon 受管 Linux 環境中執行。您可以透過 Python wheel 檔案,以編譯形式提供原生相依性。如需 Glue AWS 版本相容性詳細資訊,請參閱上表。

如果您的 Python 相依性暫時依賴於原生編譯的程式碼,您可以根據下列限制執行: AWS Glue 不支援在任務環境中編譯原生程式碼。不過, AWS Glue 任務會在 Amazon 受管 Linux 環境中執行。您可以透過車輪分佈,以編譯形式提供原生相依性。如需 Glue AWS 版本相容性詳細資訊,請參閱上表。

重要

使用不相容的相依性可能會導致執行期問題,特別是對於具有原生擴充功能的程式庫,這些擴充功能必須符合目標環境的架構和系統程式庫。每個 AWS Glue 版本都會在具有預先安裝程式庫和系統組態的特定 Python 版本上執行。

在 AWS Glue 2.0 或更新版本中使用 pip 安裝其他 Python 模組

AWS Glue 使用 Python 套件安裝程式 (pip3) 來安裝 AWS Glue ETL 要使用的其他模組。您可以使用 --additional-python-modules 參數與逗號分隔的 Python 模組清單來新增新模組或變更現有模組的版本。您可以將分佈上傳到 Amazon S3 來安裝程式庫的自訂發行版本,然後在模組清單中包含 Amazon S3 物件的路徑。

您可以使用 --python-modules-installer-option 參數將其他選項傳遞給 pip3。例如,您可以傳遞 "--upgrade" 來升級由 "--additional-python-modules" 指定的套件。如需更多範例,請參閱使用 Glue 2.0 從 Spark ETL AWS 工作負載的 wheel 建置 Python 模組。

AWS Glue 支援使用存放在 Amazon S3 中的 wheel (.whl) 檔案安裝自訂 Python 套件。若要在 Glue AWS 任務中包含輪子檔案,請將儲存在 s3 中的輪子檔案的逗號分隔清單提供給--additional-python-modules任務參數。例如:

--additional-python-modules s3://amzn-s3-demo-bucket/path/to/package-1.0.0-py3-none-any.whl,s3://your-bucket/path/to/another-package-2.1.0-cp311-cp311-linux_x86_64.whl

當您需要自訂分佈,或具有原生相依性的套件已針對正確的作業系統預先編譯時,此方法也支援 。如需更多範例,請參閱使用 Glue 2.0 從 Spark ETL 工作負載的 wheel AWS 建置 Python 模組。

您可以在 Glue AWS 主控台--additional-python-modules的任務參數欄位中指定 ,或是透過修改 AWS SDK 中的任務引數來指定 。如需設定任務參數的詳細資訊,請參閱在 Glue AWS 任務中使用任務參數

在 AWS Glue 5.0 中,您可以提供 defacto 標準requirements.txt來管理 Python 程式庫相依性。若要這樣做,請提供下列兩個任務參數:

  • 索引鍵:--python-modules-installer-option

    值:-r

  • 索引鍵:--additional-python-modules

    值:s3://path_to_requirements.txt

AWS Glue 5.0 節點一開始會載入 中指定的 Python 程式庫。 requirements.txt

以下是範例 requirements.txt:

awswrangler==3.9.1 elasticsearch==8.15.1 PyAthena==3.9.0 PyMySQL==1.1.1 PyYAML==6.0.2 pyodbc==5.2.0 pyorc==0.9.0 redshift-connector==2.1.3 scipy==1.14.1 scikit-learn==1.5.2 SQLAlchemy==2.0.36
重要

請避免在 requirements.txt 中取消鎖定程式庫版本,以確保您的任務具有可靠且決定性的 AWS Glue 環境。

當您將 wheel 用於直接相依性時,如果未正確鎖定,則可以引入不相容的傳輸相依性版本。作為最佳實務,所有程式庫版本都應固定,以確保 Glue AWS 任務的一致性。 AWS Glue 建議將您的 python 環境封裝到 wheel 檔案中,以確保生產工作負載的一致性和可靠性。

若要更新或新增 Python 模組 AWS Glue,允許使用逗號分隔 Python 模組的清單做為值傳遞--additional-python-modules參數。例如,若要更新/新增 scikit-learn 模組,請使用下列索引鍵/值:"--additional-python-modules", "scikit-learn==0.21.3"。您有兩個選項可以直接設定 python 模組。

  • 固定 Python 模組 (建議)

    "--additional-python-modules", "scikit-learn==0.21.3,ephem==4.1.6"

  • 未固定的 Python 模組:(不建議用於生產工作負載)

    "--additional-python-modules", "scikit-learn>==0.20.0,ephem>=4.0.0"

    "--additional-python-modules", "scikit-learn,ephem"

重要

直接在 中設定 Python 模組時--additional-python-modules, AWS Glue 建議使用固定程式庫版本,以確保 Glue AWS 任務環境中的一致性。使用未鎖定的程式庫版本, 會提取最新版本的 python 模組,但這可能會導致突破性的變更,或導致不相容的 python AWS 模組因 Glue 任務環境中的 python 安裝失敗而導致任務失敗。我們建議客戶不要將未鎖定的程式庫版本用於生產工作負載。最佳實務是, AWS Glue 建議您將 python 環境封裝到 wheel 檔案中,以確保生產工作負載的一致性和可靠性。

在 Glue 中安裝其他 Python AWS 程式庫的最佳實務

(建議) 將 Python 環境封裝為單一 wheel 檔案

為了安全且一致的環境, AWS Glue 建議您將 python 環境快照並封裝成 wheel 檔案。這樣做的好處是,用於參考 python 模組的 python 環境及其傳輸相依性將被鎖定。這可確保當 PyPI AWS 或相依性等上游儲存庫引入不相容的更新時,您的 Glue 任務不會受到影響。

然後,您可以使用 --additional-python-modules旗標將此檔案用於 Glue AWS 任務。

重要

您必須在與您執行的 Glue AWS 版本類似的環境中執行下列指令碼。請參閱黏附環境詳細資訊表,並確保您使用的是相同的基礎作業系統映像和 python 版本。

#!/bin/bash set -e REQUIREMENTS_FILE="requirements.txt" FINAL_WHEEL_OUTPUT_DIRECTORY="." PACKAGE_NAME=$(basename "$(pwd)") PACKAGE_VERSION="0.1.0" # Help message show_help() { echo "Usage: $0 [options]" echo "" echo "Options:" echo " -r, --requirements FILE Path to requirements.txt file (default: requirements.txt)" echo " -o, --wheel-output DIR Output directory for final wheel (default: current directory)" echo " -n, --name NAME Package name (default: current directory name)" echo " -v, --version VERSION Package version (default: 0.1.0)" echo " -h, --help Show this help message" echo " -g, --glue-version Glue version (required)" echo "" echo "Example:" echo " $0 -r custom-requirements.txt -o dist -n my_package -v 1.2.3 -g 4.0" } # Parse command line arguments while [[ $# -gt 0 ]]; do key="$1" case $key in -r | --requirements) REQUIREMENTS_FILE="$2" shift 2 ;; -o | --wheel-output) FINAL_WHEEL_OUTPUT_DIRECTORY="$2" shift 2 ;; -n | --name) PACKAGE_NAME="$2" shift 2 ;; -v | --version) PACKAGE_VERSION="$2" shift 2 ;; -g | --glue-version) GLUE_VERSION="$2" shift 2 ;; -h | --help) show_help exit 0 ;; *) echo "Unknown option: $1" show_help exit 1 ;; esac done # If package name has dashes, convert to underscores and notify user. We need to check this since we cant import a package with dashes. if [[ "$PACKAGE_NAME" =~ "-" ]]; then echo "Warning: Package name '$PACKAGE_NAME' contains dashes. Converting to underscores." PACKAGE_NAME=$(echo "$PACKAGE_NAME" | tr '-' '_') fi UBER_WHEEL_NAME="${PACKAGE_NAME}-${PACKAGE_VERSION}-py3-none-any.whl" # Check if glue version is provided if [ -z "$GLUE_VERSION" ]; then echo "Error: Glue version is required." exit 1 fi # Validate version format (basic check) if [[ ! "$PACKAGE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ ! "$PACKAGE_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then echo "Warning: Version '$PACKAGE_VERSION' doesn't follow semantic versioning (x.y.z or x.y)" fi # Check if requirements file exists if [ ! -f "$REQUIREMENTS_FILE" ]; then echo "Error: Requirements file '$REQUIREMENTS_FILE' not found." exit 1 fi # Get relevant platform tags/python versions based on glue version if [[ "$GLUE_VERSION" == "5.0" ]]; then PYTHON_VERSION="3.11" GLIBC_VERSION="2.34" elif [[ "$GLUE_VERSION" == "4.0" ]]; then PYTHON_VERSION="3.10" GLIBC_VERSION="2.26" elif [[ "$GLUE_VERSION" == "3.0" ]]; then PYTHON_VERSION="3.7" GLIBC_VERSION="2.26" elif [[ "$GLUE_VERSION" == "2.0" ]]; then PYTHON_VERSION="3.7" GLIBC_VERSION="2.17" elif [[ "$GLUE_VERSION" == "1.0" ]]; then PYTHON_VERSION="3.6" GLIBC_VERSION="2.17" elif [[ "$GLUE_VERSION" == "0.9" ]]; then PYTHON_VERSION="2.7" GLIBC_VERSION="2.17" else echo "Error: Unsupported glue version '$GLUE_VERSION'." exit 1 fi echo "Using Glue version $GLUE_VERSION" echo "Using Glue python version $PYTHON_VERSION" echo "Using Glue glibc version $GLIBC_VERSION" PIP_PLATFORM_FLAG="" is_glibc_compatible() { # assumes glibc version in the form of major.minor (ex: 2.17) # glue glibc must be >= platform glibc local glue_glibc_version="$GLIBC_VERSION" local platform_glibc_version="$1" # 2.27 (platform) can run on 2.27 (glue) if [[ "$platform_glibc_version" == "$glue_glibc_version" ]]; then return 0 fi local glue_glibc_major="${glue_glibc_version%%.*}" local glue_glibc_minor="${glue_glibc_version#*.}" local platform_glibc_major="${platform_glibc_version%%.*}" local platform_glibc_minor="${platform_glibc_version#*.}" # 3.27 (platform) cannot run on 2.27 (glue) if [[ "$platform_glibc_major" -gt "$glue_glibc_major" ]]; then return 1 fi # 2.34 (platform) cannot run on 2.27 (glue) if [[ "$platform_glibc_major" -eq "$glue_glibc_major" ]] && [[ "$platform_glibc_minor" -gt "$glue_glibc_minor" ]]; then return 1 fi # 2.17 (platform) can run on 2.27 (glue) return 0 } PIP_PLATFORM_FLAG="" if is_glibc_compatible "2.17"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux2014_x86_64" fi if is_glibc_compatible "2.28"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux_2_28_x86_64" fi if is_glibc_compatible "2.34"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux_2_34_x86_64" fi if is_glibc_compatible "2.39"; then PIP_PLATFORM_FLAG="${PIP_PLATFORM_FLAG} --platform manylinux_2_39_x86_64" fi echo "Using pip platform flags: $PIP_PLATFORM_FLAG" # Convert to absolute paths REQUIREMENTS_FILE=$(realpath "$REQUIREMENTS_FILE") FINAL_WHEEL_OUTPUT_DIRECTORY=$(realpath "$FINAL_WHEEL_OUTPUT_DIRECTORY") TEMP_WORKING_DIR=$(mktemp -d) VENV_DIR="${TEMP_WORKING_DIR}/.build_venv" WHEEL_OUTPUT_DIRECTORY="${TEMP_WORKING_DIR}/wheelhouse" # Cleanup function cleanup() { echo "Cleaning up temporary files..." rm -rf "$TEMP_WORKING_DIR" } trap cleanup EXIT echo "=========================================" echo "Building wheel for $PACKAGE_NAME with all dependencies from $REQUIREMENTS_FILE" echo "=========================================" # Determine Python executable to use consistently PYTHON_EXEC=$(which python3 2>/dev/null || which python 2>/dev/null) if [ -z "$PYTHON_EXEC" ]; then echo "Error: No Python executable found" exit 1 fi echo "Using Python: $PYTHON_EXEC" echo "" # Install build requirements echo "Step 1/5: Installing build tools..." echo "----------------------------------------" "$PYTHON_EXEC" -m pip install --upgrade pip build wheel setuptools echo "✓ Build tools installed successfully" echo "" # Create a virtual environment for building echo "Step 2/5: Creating build environment..." echo "----------------------------------------" "$PYTHON_EXEC" -m venv "$VENV_DIR" # Check if virtual environment was created successfully if [ ! -f "$VENV_DIR/bin/activate" ]; then echo "Error: Failed to create virtual environment" exit 1 fi source "$VENV_DIR/bin/activate" # Install pip-tools for dependency resolution "$VENV_DIR/bin/pip" install pip-tools echo "✓ Build environment created successfully" echo "" # Compile requirements to get all transitive dependencies GLUE_PIP_ARGS="$PIP_PLATFORM_FLAG --python-version $PYTHON_VERSION --only-binary=:all:" echo "Step 3/5: Resolving all dependencies..." echo "----------------------------------------" if ! "$VENV_DIR/bin/pip-compile" --pip-args "$GLUE_PIP_ARGS" --no-emit-index-url --output-file "$TEMP_WORKING_DIR/.compiled_requirements.txt" "$REQUIREMENTS_FILE"; then echo "Error: Failed to resolve dependencies. Check for conflicts in $REQUIREMENTS_FILE" exit 1 fi echo "✓ Dependencies resolved successfully" echo "" # Download all wheels for dependencies echo "Step 4/5: Downloading all dependency wheels..." echo "----------------------------------------" "$VENV_DIR/bin/pip" download -r "$TEMP_WORKING_DIR/.compiled_requirements.txt" -d "$WHEEL_OUTPUT_DIRECTORY" $GLUE_PIP_ARGS # Check if any wheels were downloaded if [ ! "$(ls -A "$WHEEL_OUTPUT_DIRECTORY")" ]; then echo "Error: No wheels were downloaded. Check your requirements file." exit 1 fi # Count downloaded wheels (using find instead of ls for better handling) WHEEL_COUNT=$(find "$WHEEL_OUTPUT_DIRECTORY" -name "*.whl" -type f | wc -l | tr -d ' ') echo "✓ Downloaded $WHEEL_COUNT dependency wheels successfully" echo "" # Create a single uber wheel with all dependencies echo "Step 5/5: Creating uber wheel with all dependencies included..." echo "----------------------------------------" # Create a temporary directory for the uber wheel UBER_WHEEL_DIR="$TEMP_WORKING_DIR/uber" mkdir -p "$UBER_WHEEL_DIR" # Create the setup.py file with custom install command cat >"$UBER_WHEEL_DIR/setup.py" <<EOF from setuptools import setup, find_packages import setuptools.command.install import os import glob import subprocess import sys setup( name='${PACKAGE_NAME}', version='${PACKAGE_VERSION}', description='Bundle containing dependencies for ${PACKAGE_NAME}', author='Package Builder', author_email='builder@example.com', packages=['${PACKAGE_NAME}'], # Include the package directory to hold wheels include_package_data=True, package_data={ '${PACKAGE_NAME}': ['wheels/*.whl'], # Include wheels in the package directory } ) EOF # Create a MANIFEST.in file to include all wheels cat >"$UBER_WHEEL_DIR/MANIFEST.in" <<EOF recursive-include ${PACKAGE_NAME}/wheels *.whl EOF # Create an __init__.py file that imports all the bundled wheel files (no auto-install logic) mkdir -p "$UBER_WHEEL_DIR/${PACKAGE_NAME}" cat >"$UBER_WHEEL_DIR/${PACKAGE_NAME}/__init__.py" <<EOF """ ${PACKAGE_NAME} - dependencies can be installed at runtime using the $(load_wheels) function """ from pathlib import Path import logging import subprocess import sys __version__ = "${PACKAGE_VERSION}" def load_wheels(log_level=logging.INFO): logger = logging.getLogger(__name__) handler = logging.StreamHandler(sys.stdout) formatter = logging.Formatter("[Glue Python Wheel Installer] %(asctime)s - %(name)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(log_level) logger.info("Starting wheel installation process") package_dir = Path(__file__).parent.absolute() wheels_dir = package_dir / "wheels" logger.debug(f"Package directory: {package_dir}") logger.debug(f"Looking for wheels in: {wheels_dir}") if not wheels_dir.exists(): logger.error(f"Wheels directory not found: {wheels_dir}") return False wheel_files = list(wheels_dir.glob("*.whl")) if not wheel_files: logger.warning(f"No wheels found in: {wheels_dir}") return False logger.info(f"Found {len(wheel_files)} wheels") wheel_file_paths = [str(wheel_file) for wheel_file in wheel_files] logger.info(f"Installing {wheel_file_paths}...") try: result = subprocess.run( [sys.executable, "-m", "pip", "install", *wheel_file_paths], check=True, capture_output=True, text=True ) logger.info(f"✓ Successfully installed wheel files") logger.debug(f"pip output: {result.stdout}") except subprocess.CalledProcessError as e: error_msg = f"Failed to install wheel files" logger.error(f"✗ {error_msg}: {e}") if e.stderr: logger.error(f"Error details: {e.stderr}") return False logger.info("All wheels installed successfully") return True EOF cat >"$UBER_WHEEL_DIR/${PACKAGE_NAME}/auto.py" <<EOF """ ${PACKAGE_NAME} - utility module that allows users to automatically install modules by adding $(import ${PACKAGE_NAME}.auto) to the top of their script """ from ${PACKAGE_NAME} import load_wheels load_wheels() EOF # Copy all wheels to the uber wheel directory mkdir -p "$UBER_WHEEL_DIR/${PACKAGE_NAME}/wheels" cp "$WHEEL_OUTPUT_DIRECTORY"/*.whl "$UBER_WHEEL_DIR/${PACKAGE_NAME}/wheels/" # Build the uber wheel echo "Building uber wheel package..." # Install build tools in the current environment "$VENV_DIR/bin/pip" install build if ! (cd "$UBER_WHEEL_DIR" && "$VENV_DIR/bin/python" -m build --skip-dependency-check --wheel --outdir .); then echo "Error: Failed to build uber wheel" exit 1 fi # Ensure output directory exists mkdir -p "$FINAL_WHEEL_OUTPUT_DIRECTORY" # Copy the uber wheel to the output directory FINAL_WHEEL_OUTPUT_PATH="$FINAL_WHEEL_OUTPUT_DIRECTORY/$UBER_WHEEL_NAME" # Find the generated wheel (should be only one in the root directory) GENERATED_WHEEL=$(find "$UBER_WHEEL_DIR" -maxdepth 1 -name "*.whl" -type f | head -1) if [ -z "$GENERATED_WHEEL" ]; then echo "Error: No uber wheel was generated" exit 1 fi cp "$GENERATED_WHEEL" "$FINAL_WHEEL_OUTPUT_PATH" # Get final wheel size for user feedback WHEEL_SIZE=$(du -h "$FINAL_WHEEL_OUTPUT_PATH" | cut -f1) echo "✓ Uber wheel created successfully!" echo "" echo "=========================================" echo "BUILD COMPLETED SUCCESSFULLY!" echo "=========================================" echo "Final wheel: $FINAL_WHEEL_OUTPUT_PATH" echo "Wheel size: $WHEEL_SIZE" echo "Dependencies included: $WHEEL_COUNT packages" echo "" echo "To install the bundle, run:" echo " pip install $FINAL_WHEEL_OUTPUT_PATH" echo "" echo "After installation, you can verify that the bundle works by running:" echo " python -c \"import ${PACKAGE_NAME}; ${PACKAGE_NAME}.load_wheels()\"" echo " or " echo " python -c \"import ${PACKAGE_NAME}.auto\"" echo "========================================="

./wheel_packager.sh -r <path to requirements.txt> -g <glue version> -o <wheel output directory> -n <package name> -v <wheel version>

--additional-python-modules s3://your-bucket/path/to/package_with_dependencies-1.0.0-py3-none-any.whl

# Option 1: automatic installation via import import package_with_dependencies.auto # Option 2: manual installation from package_with_dependencies import load_wheels load_wheels()

包括 Python 檔案與 PySpark 原生功能

AWS Glue 使用 PySpark 在 Glue ETL AWS 任務中包含 Python 檔案。您需使用可用的 --additional-python-modules 管理相依性。您可以使用 --extra-py-files 任務參數來包含 Python 檔案。相依性必須在 Amazon S3 中託管,且引數值應為以逗號分隔的 Amazon S3 路徑清單,並不含空格。此功能的行為類似於您搭配 Spark 使用的 Python 相依性管理。有關 Spark 中 Python 相依性管理的詳細資訊,請參閱 Apache Spark 文件中的 Using PySpark Native Features (使用 PySpark 原生功能) 頁面。在未封裝其他程式碼的情況下,或者當您使用現有工具鏈遷移 Spark 程式以管理相依性時,--extra-py-files 非常有用。為了使您的相依性工具可維護,您必須在提交之前綁定相依性。

使用視覺化轉換的程式設計指令碼

當您使用 AWS Glue Studio 視覺化界面建立 Glue AWS 任務時,您可以使用受管資料轉換節點和自訂視覺化轉換來轉換資料。如需受管資料轉換節點的詳細資訊,請參閱 使用AWS Glue受管轉換轉換資料。如需自訂視覺效果轉換的詳細資訊,請參閱 使用自訂視覺效果轉換轉換資料 。只有在任務語言設定為使用 Python 時,才能使用視覺化轉換產生指令碼。

使用視覺化轉換產生 AWS Glue 任務時, AWS Glue Studio 會使用任務組態中的 --extra-py-files 參數,將這些轉換包含在執行時間環境中。如需有關任務參數的詳細資訊,請參閱 在 Glue AWS 任務中使用任務參數。變更產生的指令碼或執行時間環境時,您需要保留此任務組態,指令碼才能成功執行。

壓縮程式庫以加入

除非程式庫包含在單一的 .py 檔案裡,否則應封裝於 .zip 封存中。套件目錄應位於封存的根目錄,且套件必須包含一個 __init__.py 檔案。接著 Python 就可以正常匯入套件。

如果程式庫僅由一個 .py 檔案裡的單一 Python 模組組成,則不必將其置於 .zip 檔案。

在 Glue Studio AWS 筆記本中載入 Python 程式庫

若要在 Glue Studio AWS 筆記本中指定 Python 程式庫,請參閱安裝其他 Python 模組。

在 Glue 0.9/1.0 中的開發端點中載入 Python AWS 程式庫

若要將不同的程式庫集用於不同的 ETL 指令碼,您可以為各程式庫集設定個別的開發端點,或是覆寫每次切換指令碼時開發端點載入的程式庫 .zip 檔案。

在建立開發端點時,您可以使用主控台為其指定一或多個程式庫 .zip 檔案。指派名稱和 IAM 角色後,請選擇 Script Libraries and job parameters (optional) [指令碼程式庫與任務參數 (選用)],並在 .zipPython library path (Python 程式庫路徑) 方塊中輸入程式庫 檔案的完整 Amazon S3 路徑。例如:

s3://bucket/prefix/site-packages.zip

您也可以為檔案指定多個完整路徑,以逗號但不含空格的方式隔開,例如:

s3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip

如果您在後來更新這些 .zip 檔案,您可以使用主控台將檔案重新匯入開發端點。導覽至該開發端點,從 Action (動作) 選單選擇 Update ETL libraries (更新 ETL 程式庫)。

以類似的方式,您可以使用 Glue APIs AWS 指定程式庫檔案。呼叫 CreateDevEndpoint 動作 (Python: create_dev_endpoint) 以建立開發端點時,您可以在 ExtraPythonLibsS3Path 參數中為程式庫指定一個或多個完整路徑,而呼叫的格式如下:

dep = glue.create_dev_endpoint( EndpointName="testDevEndpoint", RoleArn="arn:aws:iam::123456789012", SecurityGroupIds="sg-7f5ad1ff", SubnetId="subnet-c12fdba4", PublicKey="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtp04H/y...", NumberOfNodes=3, ExtraPythonLibsS3Path="s3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip")

更新開發端點時,您也可以更新其載入的程式庫,方式是使用 DevEndpointCustomLibraries 物件,並在呼叫 UpdateDevEndpoint (update_dev_endpoint) 時將 UpdateEtlLibraries 參數設定為 True

在任務或 JobRun 使用 Python 程式庫

在主控台建立新任務時,您可以指定一個或多個程式庫 .zip 檔案,方式是選擇 Script Libraries and job parameters (optional) (指令碼程式庫與任務參數 (選用)),並以與建立開發端點相同的方式輸入完整 Amazon S3 路徑:

s3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip

若要呼叫 CreateJob (create_job),您可以使用 --extra-py-files 預設參數來為預設程式庫指定一個或多個完整路徑,如下所示:

job = glue.create_job(Name='sampleJob', Role='Glue_DefaultRole', Command={'Name': 'glueetl', 'ScriptLocation': 's3://my_script_bucket/scripts/my_etl_script.py'}, DefaultArguments={'--extra-py-files': 's3://bucket/prefix/lib_A.zip,s3://bucket_B/prefix/lib_X.zip'})

接著,啟動 JobRun 時,您可以用不同的內容覆寫預設程式庫設定:

runId = glue.start_job_run(JobName='sampleJob', Arguments={'--extra-py-files': 's3://bucket/prefix/lib_B.zip'})

主動分析 Python 相依性

若要在部署到 Glue AWS 之前主動識別潛在的相依性問題,您可以使用相依性分析工具,根據目標 Glue 環境驗證 Python AWS 套件。

AWS 提供專為 Glue 環境設計的開放原始碼 Python AWS 相依性分析器工具。此工具可在 AWS Glue 範例儲存庫中使用,並可在本機用於在部署之前驗證您的相依性。

此分析有助於確保您的相依性遵循鎖定所有程式庫版本以實現一致生產部署的建議實務。如需詳細資訊,請參閱工具的 README

AWS Glue Python 相依性分析器透過使用符合您目標 Glue AWS 環境的平台特定限制來模擬 pip 安裝,協助識別未鎖定的相依性和版本衝突。

# Analyze a single Glue job python glue_dependency_analyzer.py -j my-glue-job # Analyze multiple jobs with specific AWS configuration python glue_dependency_analyzer.py -j job1 -j job2 --aws-profile production --aws-region us-west-2

工具會標記:

  • 可跨任務執行安裝不同版本的未鎖定相依性

  • 套件之間的版本衝突

  • 您的目標 Glue AWS 環境無法使用相依性

Amazon Q Developer 是生成式人工智慧 (AI) 支援的對話式助理,可協助您了解、建置、擴展和操作 AWS 應用程式。您可以依照 Amazon Q 入門指南中的指示進行下載。

Amazon Q Developer 可用來分析和修正因 python 相依性而導致的任務失敗。我們建議您使用下列提示,將任務 <Job-Name> 預留位置取代為您的黏附任務名稱。

I have an AWS Glue job named <Job-Name> that has failed due to Python module installation conflicts. Please assist in diagnosing and resolving this issue using the following systematic approach. Proceed once sufficient information is available. Objective: Implement a fix that addresses the root cause module while minimizing disruption to the existing working environment. Step 1: Root Cause Analysis • Retrieve the most recent failed job run ID for the specified Glue job • Extract error logs from CloudWatch Logs using the job run ID as a log stream prefix • Analyze the logs to identify: • The recently added or modified Python module that triggered the dependency conflict • The specific dependency chain causing the installation failure • Version compatibility conflicts between required and existing modules Step 2: Baseline Configuration Identification • Locate the last successful job run ID prior to the dependency failure • Document the Python module versions that were functioning correctly in that baseline run • Establish the compatible version constraints for conflicting dependencies Step 3: Targeted Resolution Implementation • Apply pinning by updating the job's additional_python_modules parameter • Pin only the root cause module and its directly conflicting dependencies to compatible versions, and do not remove python modules unless necessary • Preserve flexibility for non-conflicting modules by avoiding unnecessary version constraints • Deploy the configuration changes with minimal changes to the existing configuration and execute a validation test run. Do not change the Glue versions. Implementation Example: Scenario: Recently added pandas==2.0.0 to additional_python_modules Error: numpy version conflict (pandas 2.0.0 requires numpy>=1.21, but existing job code requires numpy<1.20) Resolution: Update additional_python_modules to "pandas==1.5.3,numpy==1.19.5" Rationale: Use pandas 1.5.3 (compatible with numpy 1.19.5) and pin numpy to last known working version Expected Outcome: Restore job functionality with minimal configuration changes while maintaining system stability.

提示指示 Q 執行下列動作:

  1. 擷取最新失敗的任務執行 ID

  2. 尋找相關聯的日誌和詳細資訊

  3. 尋找成功的任務執行,以偵測任何變更的 Python 套件

  4. 進行任何組態修正並觸發另一個測試執行

Python 模組已在 Glue AWS 中提供

若要變更這些已提供模組的版本,請提供帶有 --additional-python-modules 任務參數的新版本。

AWS Glue version 5.0

AWS Glue 5.0 版包含以下立即可用的 Python 模組:

  • aiobotocore==2.13.1

  • aiohappyeyeballs==2.3.5

  • aiohttp==3.10.1

  • aioitertools==0.11.0

  • aiosignal==1.3.1

  • appdirs==1.4.4

  • attrs==24.2.0

  • boto3==1.34.131

  • botocore==1.34.131

  • certifi==2024.7.4

  • charset-normalizer==3.3.2

  • contourpy==1.2.1

  • cycler==0.12.1

  • fonttools==4.53.1

  • frozenlist==1.4.1

  • fsspec==2024.6.1

  • idna==2.10

  • jmespath==0.10.0

  • kaleido==0.2.1

  • kiwisolver==1.4.5

  • matplotlib==3.9.0

  • multidict==6.0.5

  • numpy==1.26.4

  • packaging==24.1

  • pandas==2.2.2

  • blocked=10.4.0

  • pip==23.0.1

  • plotly==5.23.0

  • pyarrow==17.0.0

  • pyparsing==3.1.2

  • python-dateutil==2.9.0.post0

  • pytz==2024.1

  • request==2.32.2

  • s3fs==2024.6.1

  • s3transfer==0.10.2

  • seaborn==0.13.2

  • setuptools==59.6.0

  • six==1.16.0

  • 韌性==9.0.0

  • tzdata==2024.1

  • urllib3==1.25.10

  • virtualenv==20.4.0

  • wrapt==1.16.0

  • yarl==1.9.4

AWS Glue version 4.0

AWS Glue 4.0 版包含以下立即可用的 Python 模組:

  • aiobotocore==2.4.1

  • aiohttp==3.8.3

  • aioitertools==0.11.0

  • aiosignal==1.3.1

  • async-timeout==4.0.2

  • asynctest==0.13.0

  • attrs==22.2.0

  • avro-python3==1.10.2

  • boto3==1.24.70

  • botocore==1.27.59

  • certifi==2021.5.30

  • chardet==3.0.4

  • charset-normalizer==2.1.1

  • click==8.1.3

  • cycler==0.10.0

  • Cython==0.29.32

  • fsspec==2021.8.1

  • idna==2.10

  • importlib-metadata==5.0.0

  • jmespath==0.10.0

  • joblib==1.0.1

  • kaleido==0.2.1

  • kiwisolver==1.4.4

  • matplotlib==3.4.3

  • mpmath==1.2.1

  • multidict==6.0.4

  • nltk==3.7

  • numpy==1.23.5

  • packaging==23.0

  • pandas==1.5.1

  • patsy==0.5.1

  • Pillow==9.4.0

  • pip==23.0.1

  • plotly==5.16.0

  • pmdarima==2.0.1

  • ptvsd==4.3.2

  • pyarrow==10.0.0

  • pydevd==2.5.0

  • pyhocon==0.3.58

  • PyMySQL==1.0.2

  • pyparsing==2.4.7

  • python-dateutil==2.8.2

  • pytz==2021.1

  • PyYAML==6.0.1

  • regex==2022.10.31

  • requests==2.23.0

  • s3fs==2022.11.0

  • s3transfer==0.6.0

  • scikit-learn==1.1.3

  • scipy==1.9.3

  • setuptools==49.1.3

  • six==1.16.0

  • statsmodels==0.13.5

  • subprocess32==3.5.4

  • sympy==1.8

  • tbats==1.1.0

  • threadpoolctl==3.1.0

  • tqdm==4.64.1

  • typing_extensions==4.4.0

  • urllib3==1.25.11

  • wheel==0.37.0

  • wrapt==1.14.1

  • yarl==1.8.2

  • zipp==3.10.0

AWS Glue version 3.0

AWS Glue 3.0 版包含以下立即可用的 Python 模組:

  • aiobotocore==1.4.2

  • aiohttp==3.8.3

  • aioitertools==0.11.0

  • aiosignal==1.3.1

  • async-timeout==4.0.2

  • asynctest==0.13.0

  • attrs==22.2.0

  • avro-python3==1.10.2

  • boto3==1.18.50

  • botocore==1.21.50

  • certifi==2021.5.30

  • chardet==3.0.4

  • charset-normalizer==2.1.1

  • click==8.1.3

  • cycler==0.10.0

  • Cython==0.29.4

  • docutils==0.17.1

  • enum34==1.1.10

  • frozenlist==1.3.3

  • fsspec==2021.8.1

  • idna==2.10

  • importlib-metadata==6.0.0

  • jmespath==0.10.0

  • joblib==1.0.1

  • kiwisolver==1.3.2

  • matplotlib==3.4.3

  • mpmath==1.2.1

  • multidict==6.0.4

  • nltk==3.6.3

  • numpy==1.19.5

  • packaging==23.0

  • pandas==1.3.2

  • patsy==0.5.1

  • Pillow==9.4.0

  • pip==23.0

  • pmdarima==1.8.2

  • ptvsd==4.3.2

  • pyarrow==5.0.0

  • pydevd==2.5.0

  • pyhocon==0.3.58

  • PyMySQL==1.0.2

  • pyparsing==2.4.7

  • python-dateutil==2.8.2

  • pytz==2021.1

  • PyYAML==5.4.1

  • regex==2022.10.31

  • requests==2.23.0

  • s3fs==2021.8.1

  • s3transfer==0.5.0

  • scikit-learn==0.24.2

  • scipy==1.7.1

  • six==1.16.0

  • Spark==1.0

  • statsmodels==0.12.2

  • subprocess32==3.5.4

  • sympy==1.8

  • tbats==1.1.0

  • threadpoolctl==3.1.0

  • tqdm==4.64.1

  • typing_extensions==4.4.0

  • urllib3==1.25.11

  • wheel==0.37.0

  • wrapt==1.14.1

  • yarl==1.8.2

  • zipp==3.12.0

AWS Glue version 2.0

AWS Glue 2.0 版包含以下立即可用的 Python 模組:

  • avro-python3==1.10.0

  • awscli==1.27.60

  • boto3==1.12.4

  • botocore==1.15.4

  • certifi==2019.11.28

  • chardet==3.0.4

  • click==8.1.3

  • colorama==0.4.4

  • cycler==0.10.0

  • Cython==0.29.15

  • docutils==0.15.2

  • enum34==1.1.9

  • fsspec==0.6.2

  • idna==2.9

  • importlib-metadata==6.0.0

  • jmespath==0.9.4

  • joblib==0.14.1

  • kiwisolver==1.1.0

  • matplotlib==3.1.3

  • mpmath==1.1.0

  • nltk==3.5

  • numpy==1.18.1

  • pandas==1.0.1

  • patsy==0.5.1

  • pmdarima==1.5.3

  • ptvsd==4.3.2

  • pyarrow==0.16.0

  • pyasn1==0.4.8

  • pydevd==1.9.0

  • pyhocon==0.3.54

  • PyMySQL==0.9.3

  • pyparsing==2.4.6

  • python-dateutil==2.8.1

  • pytz==2019.3

  • PyYAML==5.3.1

  • regex==2022.10.31

  • requests==2.23.0

  • rsa==4.7.2

  • s3fs==0.4.0

  • s3transfer==0.3.3

  • scikit-learn==0.22.1

  • scipy==1.4.1

  • setuptools==45.2.0

  • six==1.14.0

  • Spark==1.0

  • statsmodels==0.11.1

  • subprocess32==3.5.4

  • sympy==1.5.1

  • tbats==1.0.9

  • tqdm==4.64.1

  • typing-extensions==4.4.0

  • urllib3==1.25.8

  • wheel==0.35.1

  • zipp==3.12.0