Python-Bibliotheken mit AWS Glue verwenden - AWS Glue

Python-Bibliotheken mit AWS Glue verwenden

Sie können zusätzliche Python-Module und -Bibliotheken für die Verwendung mit AWS Glue ETL installieren. Für AWS Glue 2.0 und höher verwendet AWS Glue den Python Package Installer (pip3), um zusätzliche Module zu installieren, die von AWS Glue ETL verwendet werden. AWS Glue bietet mehrere Optionen, um die zusätzlichen Python-Module in Ihre AWS-Glue-Auftragsumgebung zu integrieren. Sie können den Parameter „—additional-python-modules“ verwenden, um Module mithilfe von Python-Wheel-Dateien, Anforderungsdateien (requirement.txt, AWS Glue 5.0 und höher) oder einer Liste von durch Kommas getrennten Python-Modulen einzubinden.

Im Rahmen des AWS-Modells übergreifender Verantwortlichkeit sind Sie für die Verwaltung zusätzlicher Python-Module, -Bibliotheken und deren Abhängigkeiten verantwortlich, die Sie für Ihre Aufträge von AWS Glue ETL verwenden. Dies beinhaltet das Durchführen von Updates und Sicherheitspatches.

AWS Glue unterstützt die Kompilierung von nativem Code in der Auftragsumgebung nicht. AWS-Glue-Aufträge werden jedoch in einer von Amazon verwalteten Linux-Umgebung ausgeführt. Möglicherweise können Sie Ihre nativen Abhängigkeiten in einer kompilierten Form über eine Python-Wheel-Datei bereitstellen. Einzelheiten zur Kompatibilität der AWS-Glue-Version finden Sie in der obigen Tabelle.

Wenn Ihre Python-Abhängigkeiten transitiv von nativem, kompiliertem Code abhängen, kann die folgende Einschränkung auftreten: AWS Glue unterstützt das Kompilieren von nativem Code in der Auftragsumgebung nicht. AWS-Glue-Aufträge werden jedoch in einer von Amazon verwalteten Linux-Umgebung ausgeführt. Möglicherweise können Sie Ihre nativen Abhängigkeiten in einer kompilierten Form über eine Wheel-Verteilung bereitstellen. Einzelheiten zur Kompatibilität der AWS-Glue-Version finden Sie in der obigen Tabelle.

Wichtig

Die Verwendung inkompatibler Abhängigkeiten kann zu Laufzeitproblemen führen, insbesondere bei Bibliotheken mit nativen Erweiterungen, die mit der Architektur und den Systembibliotheken der Zielumgebung übereinstimmen müssen. Jede AWS-Glue-Version wird auf einer bestimmten Python-Version mit vorinstallierten Bibliotheken und Systemkonfigurationen ausgeführt.

Installieren zusätzlicher Python-Module mit pip in AWS Glue 2.0 oder höher

AWS Glue verwendet den Python Package Installer (pip3), um die zusätzlichen Module zur Verwendung mit AWS-Glue-ETL zu installieren. Sie können den Parameter „--additional-python-modules“ mit verschiedenen kommagetrennten Python-Modulen verwenden, um ein neues Modul hinzuzufügen oder die Version eines vorhandenen Moduls zu ändern. Sie können benutzerdefinierte Distributionen einer Bibliothek installieren, indem Sie die Distribution in Amazon S3 hochladen und dann den Pfad zum Amazon-S3-Objekt in Ihre Modulliste aufnehmen.

Sie können zusätzliche Optionen an pip3 übergeben mit dem Parameter --python-modules-installer-option. Sie können z. B. "--upgrade" übergeben, um die Pakete zu aktualisieren, die von "--additional-python-modules" angegeben wurden. Weitere Beispiele finden Sie unter Erstellen von Python-Modulen aus einem Rad für Spark-ETL-Workloads, die AWS Glue 2.0 verwenden.

AWS Glue unterstützt die Installation benutzerdefinierter Python-Pakete mithilfe von Wheel-Dateien (.whl), die in Amazon S3 gespeichert sind. Um Wheel-Dateien in Ihre AWS-Glue-Aufträge aufzunehmen, geben Sie dem Auftragsparameter --additional-python-modules eine kommagetrennte Liste Ihrer in S3 gespeicherten Wheel-Dateien an. Zum Beispiel:

--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

Dieser Ansatz unterstützt auch, wenn Sie benutzerdefinierte Distributionen oder Pakete mit nativen Abhängigkeiten benötigen, die für das richtige Betriebssystem vorkompiliert sind. Weitere Beispiele finden Sie unter Erstellen von Python-Modulen aus einem Rad für Spark-ETL-Workloads, die AWS Glue 2.0 verwenden.

Sie geben die --additional-python-modules im Feld „Auftragsparameter“ der AWS-Glue-Konsole oder durch Ändern der Auftragsargumente im AWS SDK an. Informationen zum Festlegen von Auftragsparametern finden Sie unter Using job parameters in AWS Glue jobs.

In AWS Glue 5.0 können Sie den Defacto-Standard requirements.txt zur Verwaltung von Python-Bibliotheksabhängigkeiten bereitstellen. Geben Sie dazu die folgenden zwei Auftragsparameter an:

  • Schlüssel: --python-modules-installer-option

    Wert: -r

  • Schlüssel: --additional-python-modules

    Wert: s3://path_to_requirements.txt

Knoten von AWS Glue 5.0 laden zunächst die in requirements.txt angegebenen Python-Bibliotheken.

Hier ist ein Beispiel für 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
Wichtig

Bitte vermeiden Sie nicht angeheftete Bibliotheksversionen in Ihrer requirements.txt, um sicherzustellen, dass Sie über eine zuverlässige und deterministische AWS-Glue-Umgebung für Ihre Aufträge verfügen.

Wenn Sie Wheel für direkte Abhängigkeiten verwenden, können Sie eine inkompatible Version Ihrer transitiven Abhängigkeiten einbringen, falls diese nicht korrekt angeheftet sind. Als bewährte Methode sollten alle Bibliotheksversionen aus Gründen der Konsistenz in AWS-Glue-Aufträgen angeheftet werden. AWS Glue empfiehlt, Ihre Python-Umgebung in eine Wheel-Datei zu packen, um Konsistenz und Zuverlässigkeit für Ihre Produktions-Workload zu gewährleisten.

Um ein neues Python-Modul zu aktualisieren oder hinzuzufügen, ermöglicht AWS Glue die Übergabe des Parameters --additional-python-modules mit verschiedenen kommagetrennten Python-Modulen als Werte. Verwenden Sie beispielsweise zur Aktualisierung/zum Hinzufügen eines scikit-learn-Moduls den folgenden Schlüssel/Wert: "--additional-python-modules", "scikit-learn==0.21.3". Sie haben zwei Möglichkeiten, die Python-Module direkt zu konfigurieren.

  • Angeheftetes Python-Modul (empfohlen)

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

  • Nicht angeheftetes Python-Modul: (Nicht für Produktions-Workloads empfohlen)

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

    ODER

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

Wichtig

Bei der Konfiguration der Python-Module direkt in --additional-python-modules empfiehlt AWS Glue, angeheftete Bibliotheksversionen zu verwenden, um die Konsistenz in der Auftragsumgebung von AWS Glue sicherzustellen. Bei Verwendung nicht angehefteter Bibliotheksversionen wird die neueste Version der Python-Module abgerufen. Dies kann jedoch zu schwerwiegenden Änderungen führen oder ein inkompatibles Python-Modul einbringen, was zu einem Auftragsfehler aufgrund eines Python-Installationsfehlers in der Auftragsumgebung von AWS Glue führt. Wir empfehlen Kunden, keine nicht angehefteten Bibliotheksversionen für Produktions-Workloads zu verwenden. Als bewährte Methode empfiehlt AWS Glue, Ihre Python-Umgebung in eine Wheel-Datei zu packen, um Konsistenz und Zuverlässigkeit für Ihre Produktions-Workload zu gewährleisten.

Bewährte Methoden für die Installation zusätzlicher Python-Bibliotheken in AWS Glue

(Empfohlen) Verpacken der Python-Umgebung in eine einzelne Wheel-Datei

Für eine sichere und konsistente Umgebung empfiehlt AWS Glue, dass Sie einen Snapshot Ihrer Python-Umgebung erstellen und in eine Wheel-Datei packen. Dies hat den Vorteil, dass Ihre Python-Umgebung für Python-Referenzmodule und ihre transitiven Abhängigkeiten gesperrt wird. Dadurch wird sichergestellt, dass Ihr AWS-Glue-Auftrag nicht beeinträchtigt wird, wenn ein Upstream-Repository wie PyPI oder Abhängigkeiten inkompatible Updates einführt.

Diese Datei kann dann mit dem Flag --additional-python-modules in Ihrem AWS-Glue-Auftrag verwendet werden.

Wichtig

Sie müssen das folgende Skript in einer ähnlichen Umgebung wie die von Ihnen ausgeführte AWS-Glue-Version ausführen. Bitte beachten Sie die Tabelle mit den Details zur Glue-Umgebung und stellen Sie sicher, dass Sie dasselbe Basis-Betriebssystem-Image und dieselbe Python-Version verwenden.

#!/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()

Hinzufügen von Python-Dateien mit nativen PySpark-Features

AWS Glue verwendet PySpark, um Python-Dateien zu Aufträgen von AWS Glue ETL hinzuzufügen. Sie sollten --additional-python-modules verwenden, um Ihre Abhängigkeiten zu verwalten (sofern verfügbar). Sie können den Auftragsparameter --extra-py-files verwenden, um Python-Dateien hinzuzufügen. Abhängigkeiten müssen in Amazon S3 gehostet werden und der Argumentwert sollte eine kommagetrennte Liste von Amazon S3-Pfaden ohne Leerzeichen sein. Diese Funktion verhält sich wie das Python-Abhängigkeitsmanagement, das Sie mit Spark verwenden würden´. Weitere Hinweise zur Python-Abhängigkeitsverwaltung in Spark finden Sie unter Verwenden von PySpark-Native-Features in der Apache-Spark-Dokumentation. --extra-py-files ist nützlich in Fällen, in denen Ihr zusätzlicher Code nicht gepackt ist oder wenn Sie ein Spark-Programm mit einer vorhandenen Toolchain zur Verwaltung von Abhängigkeiten migrieren. Damit Ihre Abhängigkeitstools wartbar sind, müssen Sie Ihre Abhängigkeiten bündeln, bevor Sie sie einreichen.

Programmierskripte, die visuelle Transformationen verwenden

Wenn Sie einen AWS-Glue-Auftrag mit der visuellen Oberfläche von AWS Glue Studio erstellen, können Sie Ihre Daten mit verwalteten Datentransformationsknoten und benutzerdefinierten visuellen Transformationen transformieren. Weitere Informationen zu verwalteten Datentransformationsknoten finden Sie unter Transformieren von Daten mit von AWS Glue verwalteten Transformationen. Weitere Informationen zu benutzerdefinierten visuellen Transformationen finden Sie unter Transformieren von Daten mit benutzerdefinierten visuellen Transformationen . Skripte, die visuelle Transformationen verwenden, können nur generiert werden, wenn die Sprache Ihres Auftrags auf die Verwendung von Python eingestellt ist.

Wenn ein AWS-Glue-Auftrag mithilfe von visuellen Transformationen generiert wird, bezieht AWS Glue Studio diese Transformationen mithilfe des Parameters --extra-py-files in der Auftragskonfiguration in die Laufzeitumgebung ein. Informationen zu Auftragsparametern finden Sie unter Verwendung von Auftragsparametern in AWS-Glue-Aufträgen. Wenn Sie Änderungen an einem generierten Skript oder einer generierten Laufzeitumgebung vornehmen, müssen Sie diese Auftragskonfiguration beibehalten, damit Ihr Skript erfolgreich ausgeführt werden kann.

Komprimieren von Bibliotheken für die Integration

Sofern eine Bibliothek nicht in einer einzigen .py-Datei enthalten ist, sollte sie in ein .zip-Archiv gepackt werden. Das Paketverzeichnis sollte sich im Stammverzeichnis des Archivs befinden und eine __init__.py-Datei für das Paket enthalten. Python ist dann in der Lage, das Paket wie gewohnt zu importieren.

Wenn Ihre Bibliothek nur aus einem einzigen Python-Modul in einer .py-Datei besteht, brauchen Sie sie nicht in einer .zip-Datei abzulegen.

Laden von Python-Bibliotheken in AWS-Glue-Studio-Notebooks

Informationen zur Angabe von Python-Bibliotheken in AWS-Glue-Studio-Notebooks finden Sie unter Installieren zusätzlicher Python-Module.

Laden von Python-Bibliotheken in einen Entwicklungsendpunkt in AWS Glue 0.9/1.0

Wenn Sie verschiedene Bibliotheks-Sets für verschiedene ETL-Skripts verwenden, können Sie entweder für jeden Satz einen eigenen Entwicklungsendpunkt einrichten oder die .zip-Bibliotheksdatei(en) überschreiben, die Ihr Entwicklungsendpunkt bei jedem Wechsel des Skripts lädt.

Sie können die Konsole verwenden, um eine oder mehrere Library.zip-Dateien für einen Entwicklungsendpunkt anzugeben, wenn Sie diesen erstellen. Nachdem Sie einen Namen und eine IAM-Rolle zugewiesen haben, wählen Sie Script Libraries and job parameters (optional) (Skript-Bibliotheken und Auftragsparameter (optional)) aus und geben Sie den vollständigen Amazon-S3-Pfad zu Ihrer .zip-Bibliotheksdatei im Feld Python library path (Python-Bibliothekspfad) ein. Zum Beispiel:

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

Wenn Sie möchten, können Sie mehrere vollständige Pfade zu Dateien angeben und diese mit Kommas, aber ohne Leerzeichen trennen:

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

Wenn Sie diese .zip-Dateien später aktualisieren, können Sie sie über die Konsole erneut in Ihren Entwicklungsendpunkt importieren. Navigieren Sie zu dem betreffenden Entwicklerendpunkt, markieren Sie das Kästchen daneben und wählen Sie Update ETL libraries (ETL-Bibliotheken aktualisieren) aus dem Menü Action (Aktion) aus.

Auf ähnliche Weise können Sie Bibliotheksdateien mit Hilfe der AWS-Glue-APIs spezifizieren. Wenn Sie einen Entwicklungsendpunkt durch den Aufruf vonAktion CreateDevEndpoint (Python: create_dev_endpoint) erstellen, können Sie einen oder mehrere vollständige Pfade zu Bibliotheken im ExtraPythonLibsS3Path-Parameter angeben, und zwar in einem Aufruf, der so aussieht:

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")

Wenn Sie einen Entwicklungsendpunkt aktualisieren, können Sie auch die geladene Bibliotheken aktualisieren, indem Sie ein DevEndpointCustomLibraries-Objekt verwenden und den UpdateEtlLibraries -Parameter beim Aufruf von UpdateDevEndpoint (update_dev_endpoint) auf True festlegen.

Python-Bibliotheken in einem Auftrag oder JobRun verwenden

Wenn Sie einen neuen Auftrag in der Konsole erstellen, können Sie eine oder mehrere Library.zip-Dateien angeben, indem Sie Script Libraries and job parameters (optional) (Skript-Bibliotheken und Auftragsparameter (optional)) auswählen und den vollständigen Amazon-S3-Bibliothekspfad wie beim Erstellen eines Entwicklungsendpunkts eingeben:

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

Wenn Sie die Funktion CreateJob (create_job) aufrufen, können Sie einen oder mehrere vollständige Pfade zu Standardbibliotheken angeben, indem Sie den --extra-py-files-Standardparameter verwenden:

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'})

Wenn Sie dann einen JobRun starten, können Sie die standardmäßige Bibliothekseinstellung mit einer anderen überschreiben:

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

Proaktives Analysieren von Python-Abhängigkeiten

Um potenzielle Abhängigkeitsprobleme vor der Bereitstellung in AWS Glue proaktiv zu identifizieren, können Sie das Abhängigkeitsanalyse-Tool verwenden, um Ihre Python-Pakete anhand Ihrer AWS-Glue-Zielumgebung zu validieren.

AWS bietet ein Open-Source-Tool zur Abhängigkeitsanalyse in Python, das speziell für AWS-Glue-Umgebungen entwickelt wurde. Dieses Tool ist im Repository mit AWS-Glue-Beispielen verfügbar und kann lokal verwendet werden, um Ihre Abhängigkeiten vor der Bereitstellung zu überprüfen.

Mithilfe dieser Analyse können Sie sicherstellen, dass Ihre Abhängigkeiten der empfohlenen Vorgehensweise folgen, alle Bibliotheksversionen für konsistente Produktionsbereitstellungen anzuheften. Weitere Informationen finden Sie in der README-Datei des Tools.

Der AWS Glue Python Dependency Analyzer hilft dabei, nicht angeheftete Abhängigkeiten und Versionskonflikte zu identifizieren, indem er die pip-Installation mit plattformspezifischen Einschränkungen simuliert, die Ihrer AWS-Glue-Zielumgebung entsprechen.

# 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

Das Tool kennzeichnet Folgendes:

  • Nicht angeheftete Abhängigkeiten, die bei verschiedenen Auftragsausführungen unterschiedliche Versionen installieren könnten

  • Versionskonflikte zwischen Paketen

  • Abhängigkeiten, die für Ihre AWS-Glue-Zielumgebung nicht verfügbar sind

Amazon Q Developer ist ein generativer von künstlicher Intelligenz (KI) gestützter Konversationsassistent, der Ihnen helfen kann, AWS-Anwendungen zu verstehen, zu erstellen, zu erweitern und zu betreiben. Sie können ihn herunterladen, indem Sie den Anweisungen im Handbuch „Erste Schritte“ für Amazon Q folgen.

Amazon Q Developer kann zum Analysieren und Beheben von Auftragsfehlern aufgrund von Python-Abhängigkeit verwendet werden. Wir empfehlen die Verwendung des folgenden Prompts, indem Sie den Platzhalter <Job-Name> durch den Namen Ihres Glue-Jobs ersetzen.

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.

Der Prompt weist Q zu Folgendem an:

  1. Abrufen der ID der letzten fehlerhaften Auftragsausführung

  2. Finden zugehöriger Protokolle und Details

  3. Finden erfolgreicher Auftragsausführungen, um geänderte Python-Pakete zu erkennen

  4. Vornehmen aller Konfigurationskorrekturen und Auslösen eines weiteren Testlaufs

Python-Module, die bereits in AWS Glue bereitgestellt wurden

Um die Version dieser bereitgestellten Module zu ändern, stellen Sie neue Versionen mit dem Auftragsparameter --additional-python-modules bereit.

AWS Glue version 5.0

AWS-Glue-Version 5.0 enthält standardmäßig die folgenden Python-Module:

  • 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

  • pillow==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

  • requests==2.32.2

  • s3fs==2024.6.1

  • s3transfer==0.10.2

  • seaborn==0.13.2

  • setuptools==59.6.0

  • six==1.16.0

  • tenacity==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-Version 4.0 enthält standardmäßig die folgenden Python-Module:

  • 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-Version 3.0 enthält standardmäßig die folgenden Python-Module:

  • 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-Version 2.0 enthält standardmäßig die folgenden Python-Module:

  • 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