Ошибка соединения Snowflake с JAR-пакетами pyspark

Вопрос или проблема

Я прочитал несколько тем по этому вопросу, но не нашел определенного ответа.

Я запускаю контейнер локально (mac os + podman)

scala: 'версия 2.12.17'

pyspark: 3.4.0

spark-3.4.0

python 3.11.4 

Я запускаю контейнер, который определен в Compose (источник: https://github.com/mzrks/pyspark-devcontainer/tree/master/.devcontainer)

version: '3'

services:
  app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
      args:
        PYTHON_VARIANT: 3.11
        JAVA_VARIANT: 17
    volumes:
      - ..:/workspace:cached
    command: sleep infinity

  pyspark:
    image: jupyter/pyspark-notebook:spark-3.4.0
    environment: 
      - JUPYTER_ENABLE_LAB=yes
    ports: 
      - 8888:8888

У меня есть почти все, что я смог найти, чтобы это заработало:

from pyspark.sql import SparkSession

## Я также пробовал ниже

import os
os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4 pyspark-shell'

## с тем, что я указал здесь в packages_so и repository, и без него

packages_so = 'net.snowflake:snowflake-jdbc:3.4.0,net.snowflake:spark-snowflake_2.12:2.11.0-spark_3.4' 
repository = "https://repo1.maven.org/maven2"

## Я пробовал несколько версий выше, я действительно не понимаю, как
## должны выглядеть номера версий? кроме spark_3.4, что означает версию spark?

spark = ( SparkSession
    .builder
    .master("local[*]")
    .appName("spark_docker")
    # .config("spark.jars.packages", "net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4")
    .config("spark.jars.packages", packages_so) \
    .config("spark.jars.repositories", repository)
    .getOrCreate()
)

sf_options = {
    "sfURL": "url",
    "sfUser": "user",
    "sfPassword": "pass",
    "sfDatabase": "SNOWFALL",
    "sfSchema": "PIPELINE",
    "sfWarehouse": "COMPUTE_WH",
    "sfRole": "role",
}
SNOWFLAKE_SOURCE_NAME = "snowflake" # также "net.snowflake.spark.snowflake"
sdf: DataFrame = (
    spark.read.format(SNOWFLAKE_SOURCE_NAME)
    .options(**sf_options)
    .option("dbtable", "SNOWFALL.PIPELINE.MYTABLE")
    .option("fetchsize", "10000")
    .load()
)

sdf.show(vertical=True, n=2)

spark.stop()

Я также пытался запустить в оболочке контейнера (источник: https://www.phdata.io/blog/how-to-connect-snowflake-using-spark/):

spark-shell --packages net.snowflake:snowflake-jdbc:3.17.0,spark-snowflake_2.12:2.16.0-spark_3.4

Мне просто не понятно, как добавить файл JAR в этот экземпляр, чтобы соединение работало

и моя ошибка всегда сводится к:

Py4JJavaError: Произошла ошибка при вызове o152.load.
: org.apache.spark.SparkClassNotFoundException: [DATA_SOURCE_NOT_FOUND] Не удалось найти источник данных: snowflake. Пожалуйста, найдите пакеты на `https://spark.apache.org/third-party-projects.html`.

Ответ или решение

Ошибка соединителя Snowflake с Jupyter PySpark: полное руководство по решению проблемы

Введение

В процессе работы с PySpark и подключениями к Snowflake многие разработчики сталкиваются с ошибками, связанными с классами и библиотеками. В данном руководстве мы будем разбирать типичную ошибку Py4JJavaError, а также предложим пошаговые решения для устранения проблемы с подключением Snowflake в вашем окружении.

Описание проблемы

Вы являетесь владельцем локального контейнера на macOS с использованием Podman, где развернут PySpark и требуемые библиотеки для работы с Snowflake. Попытка создать SparkSession и загрузить данные из Snowflake дает сбой с ошибкой:

Py4JJavaError: An error occurred while calling o152.load.
: org.apache.spark.SparkClassNotFoundException: [DATA_SOURCE_NOT_FOUND] Failed to find the data source: snowflake.

Это указывает на то, что Spark не может найти необходимые классы для работы с источником данных Snowflake в вашем окружении.

Структура решения

  1. Обновление зависимостей

    • Убедитесь, что версии библиотек snowflake-jdbc и spark-snowflake совместимы с установленной версией Spark. Рекомендуется использовать последнюю версию для Spark 3.4.0.

    Пример:

    packages_so = 'net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4' 
  2. Настройка SparkSession
    В вашем коде правильно указаны параметры для создания SparkSession, но важно убедиться, что библиотеки передаются корректно. Вместо:

    .config("spark.jars.packages", packages_so)

    попробуйте добавить явное указание для протокола:

    .config("spark.jars.packages", "net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4")
  3. Подключение к контейнеру
    Убедитесь, что необходимые JAR-файлы доступны в среде выполнения контейнера. Попробуйте выполнить команду в вашей контейнерной среде для установки пакетов:

    spark-submit --packages net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4 your_script.py
  4. Настройка переменных окружения
    Если ошибка всё ещё возникает, попробуйте явно указать репозиторий Maven:

    os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4 --repositories https://repo1.maven.org/maven2 pyspark-shell'
  5. Проверка маршрутов и версий
    Убедитесь, что у вас правильные версии Scala и используемых библиотек. Ошибка может возникнуть, если операционная система или архитектура контейнера несовместимы с установленными библиотеками.

Пример полного кода

Ниже представлен упрощенный пример на основе вашего кода:

from pyspark.sql import SparkSession
import os

os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4 --repositories https://repo1.maven.org/maven2 pyspark-shell'

spark = SparkSession.builder \
    .appName("spark_docker") \
    .master("local[*]") \
    .config("spark.jars.packages", "net.snowflake:snowflake-jdbc:3.17.0,net.snowflake:spark-snowflake_2.12:2.16.0-spark_3.4") \
    .getOrCreate()

sf_options = {
    "sfURL": "url",
    "sfUser": "user",
    "sfPassword": "pass",
    "sfDatabase": "SNOWFALL",
    "sfSchema": "PIPELINE",
    "sfWarehouse": "COMPUTE_WH",
    "sfRole": "role",
}

sdf = spark.read \
    .format("snowflake") \
    .options(**sf_options) \
    .option("dbtable", "SNOWFALL.PIPELINE.MYTABLE") \
    .option("fetchsize", "10000") \
    .load()

sdf.show(vertical=True, n=2)

spark.stop()

Заключение

Проблема с подключением Snowflake через PySpark может возникать по многим причинам, включая неправильные версии библиотек и настройки окружения. Следуя представленной инструкции, можно устранить большинство причин возникновения ошибки DATA_SOURCE_NOT_FOUND. Если у вас возникают дополнительные вопросы, рекомендуется также изучить официальную документацию Snowflake и PySpark, а также воспользоваться форумами поддержки для получения актуальной информации.

Оцените материал
Добавить комментарий

Капча загружается...