Чтение AWS glueContext не разрешает запрос sql

Я хочу читать отфильтрованные данные из экземпляра Mysql, используя задание AWS glue. Поскольку соединение jdbc с клеем не позволяет мне отодвинуть предикат, я пытаюсь явно создать соединение jdbc в моем коде.

Я хочу запустить запрос выбора с предложением where для базы данных Mysql с использованием соединения jdbc, как показано ниже.

import com.amazonaws.services.glue.GlueContext
import org.apache.spark.SparkContext
import org.apache.spark.sql.SparkSession


object TryMe {

  def main(args: Array[String]): Unit = {
    val sc: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(sc)
    val spark: SparkSession = glueContext.getSparkSession

    // Read data into a DynamicFrame using the Data Catalog metadata
    val t = glueContext.read.format("jdbc").option("url","jdbc:mysql://serverIP:port/database").option("user","username").option("password","password").option("dbtable","select * from table1 where 1=1").option("driver","com.mysql.jdbc.Driver").load()

  }
}

Не получается с ошибкой

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы найти правильный синтаксис для использования рядом с 'select * from table1, где 1 = 1 WHERE 1 = 0' в строке 1

Разве это не должно работать? Как получить отфильтрованные данные с помощью соединения JDBC без чтения всей таблицы во фрейм данных?


person Nikhil S    schedule 08.01.2019    source источник


Ответы (3)


Я думаю, проблема возникла из-за того, что вы не использовали запрос в скобках и не указали псевдоним. На мой взгляд, это должно выглядеть следующим образом:

 val t = glueContext.read.format("jdbc").option("url","jdbc:mysql://serverIP:port/database").option("user","username").option("password","password").option("dbtable","(select * from table1 where 1=1) as t1").option("driver","com.mysql.jdbc.Driver").load()

Дополнительная информация о параметрах в источниках данных SQL:

https://spark.apache.org/docs/latest/sql-data-sources-jdbc.html

Когда дело доходит до Glue и фреймворка, который предоставляет Glue, есть также опция "push_down_predicate", но я использовал эту опцию только для источников данных на основе S3. Я думаю, что это не работает с другими источниками, кроме S3 и несекционированных данных.

https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html

person j.b.gorski    schedule 15.01.2019
comment
Спасибо. Это помогло :) - person Nikhil S; 15.01.2019

Для тех, кто все еще ищет дополнительные ответы / примеры, я могу подтвердить, что опция push_down_predicate работает с источниками данных ODBC. Вот как я читаю из SQL Server (на Python).

df = glueContext.read.format("jdbc")
    .option("url","jdbc:sqlserver://server-ip:port;databaseName=db;")
    .option("user","username")
    .option("password","password")
    .option("dbtable","(select t1.*, t2.name from dbo.table1 t1 join dbo.table2 t2 on t1.id = t2.id) as users")
    .option("driver","com.microsoft.sqlserver.jdbc.SQLServerDriver")
    .load()

Это тоже работает, но НЕ так, как я ожидал. Предикат не передается в источник данных.

df = glueContext.create_dynamic_frame.from_catalog(database = "db", table_name = "db_dbo_table1", push_down_predicate = "(id >= 2850700 AND statusCode = 'ACT')")

В документации по pushDownPredicate говорится: параметр, позволяющий включить или отключить передачу предикатов в источник данных JDBC. Значение по умолчанию - true, и в этом случае Spark будет максимально использовать фильтры для источника данных JDBC.

person Duoc Tran    schedule 20.05.2020