Connexions JDBC - AWS Glue

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Connexions JDBC

Certains types de bases de données, généralement relationnelles, prennent en charge la connexion via le standard JDBC. Pour plus d'informations sur JDBC, consultez la documentation relative aux Java JDBC API. AWS Glue prend en charge nativement la connexion à certaines bases de données via ses connecteurs JDBC. Les bibliothèques JDBC sont fournies dans les tâches AWS Glue Spark. Lorsque vous vous connectez à ces types de bases de données à l'aide des bibliothèques AWS Glue, vous avez accès à un ensemble standard d'options.

Les valeurs connectionType JDBC sont les suivantes :

  • "connectionType": "sqlserver" : Désigne une connexion à une base de données Microsoft SQL Server.

  • "connectionType": "mysql" : Désigne une connexion à une base de données MySQL.

  • "connectionType": "oracle" : Désigne une connexion à une base de données Oracle.

  • "connectionType": "postgresql" : Désigne une connexion à une base de données PostgreSQL.

  • "connectionType": "redshift" : désigne une connexion à une base de données Amazon Redshift. Pour de plus amples informations, veuillez consulter Connexions Redshift.

Le tableau suivant répertorie les versions de pilote JDBC prises en charge par AWS Glue.

Produit Versions de pilotes JDBC pour Glue 4.0 Versions de pilotes JDBC pour Glue 3.0 Versions de pilotes JDBC pour Glue 0.9, 1.0, 2.0
Microsoft SQL Server 9.4.0 7.x 6.x
MySQL 8.0.23 8.0.23 5.1
Oracle Database 21,7 21,1 11.2
PostgreSQL 42,3.6 42,2,18 42.1.x
MongoDB  4.7.2 4.0.0 2.0.0
Amazon Redshift * redshift-jdbc42-2.1.0.16 redshift-jdbc41-1.2.12.1017 redshift-jdbc41-1.2.12.1017

* Pour le type de connexion Amazon Redshift, toutes les autres paires nom/valeur d'options qui sont incluses dans les options d'une connexion JDBC, y compris les options de formatage, sont transmises directement à la source de données SparkSQL sous-jacente. Dans les tâches AWS Glue avec Spark de AWS Glue 4.0 et versions ultérieures, le connecteur natif AWS Glue pour Amazon Redshift utilise l'intégration Amazon Redshift pour Apache Spark. Pour plus d'informations, consultez Intégration d'Amazon Redshift à Apache Spark. Pour les versions précédentes, consultez Amazon Redshift data source for Spark.

Pour configurer votre Amazon VPC afin de vous connecter aux magasins de données Amazon RDS à l'aide de JDBC, reportez-vous à Configuration d'Amazon VPC pour les connexions JDBC aux magasins de données Amazon RDS à partir de AWS Glue.

Note

AWS : les tâches Glue ne sont associées qu'à un seul sous-réseau lors d'une exécution. Cela peut avoir une incidence sur votre capacité à vous connecter à plusieurs sources de données par le biais de la même tâche. Ce comportement n'est pas limité aux sources JDBC.

Référence des options de connexion JDBC

Si vous avez déjà défini une connexion JDBC AWS Glue, vous pouvez réutiliser ses propriétés de configuration, telles que : URL, utilisateur et mot de passe. Vous n'avez donc pas à les spécifier dans le code en tant qu'options de connexion. Cette fonctionnalité est disponible dans les versions AWS 3.0 et ultérieures. Pour ce faire, utilisez les propriétés de connexion suivantes :

  • "useConnectionProperties" : à définir sur « true » pour indiquer que vous souhaitez utiliser la configuration à partir d'une connexion.

  • "connectionName" : saisissez le nom de connexion à partir duquel récupérer la configuration. La connexion doit être définie dans la même région que la tâche.

Utilisez ces options de connexion avec les connexions JDBC :

  • "url" : (Obligatoire) URL JDBC de la base de données.

  • "dbtable" : (obligatoire) table de la base de données à partir de laquelle la lecture doit s'effectuer. Pour les magasins de données JDBC qui prennent en charge les schémas dans une base de données, spécifiez schema.table-name. Si aucun schéma n'est fourni, c'est le schéma « public » par défaut qui est utilisé.

  • "user" : (Obligatoire) Nom d'utilisateur à utiliser lors de la connexion.

  • "password" : (Obligatoire) Mot de passe à utiliser lors de la connexion.

  • (Facultatif) les options suivantes vous permettent de fournir un pilote JDBC personnalisé. Utilisez ces options si vous devez utiliser un pilote que AWS Glue ne prend pas en charge en mode natif.

    Les tâches ETL peuvent utiliser différentes versions de pilote JDBC pour la source de données et la cible, même si la source et la cible sont le même produit de base de données. Cela vous permet de migrer des données entre les bases de données source et cible avec différentes versions. Pour utiliser ces options, vous devez d'abord charger le fichier JAR du pilote JDBC vers Amazon S3.

    • "customJdbcDriverS3Path" : chemin Amazon S3 du pilote JDBC personnalisé.

    • "customJdbcDriverClassName" : nom de la classe du pilote JDBC.

  • "bulkSize" : (Facultatif) Utilisé pour configurer des insertions parallèles pour accélérer les charges groupées dans les cibles JDBC. Spécifiez une valeur entière pour le degré de parallélisme à utiliser lors de l'écriture ou de l'insertion de données. Cette option permet d'améliorer les performances d'écriture dans les bases de données telles que le référentiel d'utilisateurs Arch (AUR).

  • "hashfield" : (facultatif) chaîne utilisée pour indiquer le nom d'une colonne de la table JDBC à utiliser pour diviser les données en partitions lors de la lecture de tables JDBC en parallèle. Indiquez « hashfield » OU « hashexpression ». Pour de plus amples informations, veuillez consulter Lecture en parallèle à partir de tables JDBC.

  • "hashexpression" : (facultatif) une clause de sélection SQL renvoyant un nombre entier. Utilisée pour diviser les données d'une table JDBC en partitions lors de la lecture de tables JDBC en parallèle. Indiquez « hashfield » OU « hashexpression ». Pour de plus amples informations, veuillez consulter Lecture en parallèle à partir de tables JDBC.

  • "hashpartitions" : (facultatif) un entier positif. Utilisé pour indiquer le nombre de lectures parallèles de la table JDBC lors de la lecture de tables JDBC en parallèle. Par défaut : 7. Pour de plus amples informations, veuillez consulter Lecture en parallèle à partir de tables JDBC.

  • "sampleQuery" : (facultatif) une instruction de requête SQL personnalisée. Utilisé pour spécifier un sous-ensemble d'informations dans une table afin de récupérer un échantillon du contenu de la table. Lorsqu'elle est configurée sans tenir compte de vos données, elle peut être moins efficace que les méthodes DynamicFrame, entraînant des délais d'attente ou des erreurs de mémoire insuffisante. Pour de plus amples informations, veuillez consulter Utiliser sampleQuery.

  • "enablePartitioningForSampleQuery" : (facultatif) une valeur booléenne. Par défaut : faux. Utilisé pour permettre la lecture des tables JDBC en parallèle lorsque vous indiquez sampleQuery. Si la valeur « true » est définie, sampleQuery doit se terminer par « where » ou « and » pour qu'AWS Glue ajoute des conditions de partitionnement. Pour de plus amples informations, veuillez consulter Utiliser sampleQuery.

  • "sampleSize" : (facultatif) un entier positif. Limite le nombre de lignes renvoyées par l'exemple de requête. Fonctionne uniquement lorsque enablePartitioningForSampleQuery a la valeur « true ». Si le partitionnement n'est pas activé, vous devez plutôt ajouter directement "limit x" dans sampleQuery pour limiter la taille. Pour de plus amples informations, veuillez consulter Utiliser sampleQuery.

Utiliser sampleQuery

Cette section explique comment utiliser sampleQuery, sampleSize et enablePartitioningForSampleQuery.

sampleQuery peut être un moyen efficace d'échantillonner quelques lignes de votre jeu de données. Par défaut, la requête est exécutée par un exécuteur unique. Lorsqu'elle est configurée sans tenir compte de vos données, elle peut être moins efficace que les méthodes DynamicFrame, entraînant des délais d'attente ou des erreurs de mémoire insuffisante. L'exécution de SQL sur la base de données sous-jacente dans le cadre de votre pipeline ETL n'est généralement nécessaire que pour des raisons de performances. Si vous essayez de prévisualiser quelques lignes de votre jeu de données, pensez à utiliser show. Si vous essayez de transformer votre jeu de données à l'aide de SQL, pensez à utiliser toDF pour définir une transformation SparkSQL par rapport à vos données dans un formulaire DataFrame.

Bien que votre requête puisse manipuler diverses tables, dbtable reste obligatoire.

Utilisation de sampleQuery pour récupérer un échantillon de votre table

Lorsque vous utilisez le comportement sampleQuery par défaut pour récupérer un échantillon de vos données, AWS Glue ne s'attend pas à un débit important. Il exécute donc votre requête sur un seul exécuteur. Afin de limiter les données que vous fournissez et de ne pas entraîner de problèmes de performances, nous vous suggérons de fournir une clause LIMIT à SQL.

Exemple Utiliser SampleQuery sans partitionnement

L'exemple de code suivant illustre comment utiliser sampleQuery sans partitionnement.

//A full sql query statement. val query = "select name from $tableName where age > 0 limit 1" val connectionOptions = JsonOptions(Map( "url" -> url, "dbtable" -> tableName, "user" -> user, "password" -> password, "sampleQuery" -> query )) val dyf = glueContext.getSource("mysql", connectionOptions) .getDynamicFrame()

Utilisation de sampleQuery sur des jeux de données plus volumineux

Si vous lisez un jeu de données volumineux, vous devrez peut-être activer le partitionnement JDBC pour interroger une table en parallèle. Pour de plus amples informations, veuillez consulter Lecture en parallèle à partir de tables JDBC. Pour utiliser sampleQuery avec le partitionnement JDBC, paramétrez enablePartitioningForSampleQuery sur la valeur « true ». L'activation de cette fonctionnalité nécessite que vous apportiez quelques modifications à votre sampleQuery.

Lorsque vous utilisez le partitionnement JDBC avec sampleQuery, votre requête doit se terminer par « where » ou « and » pour que AWS Glue ajoute des conditions de partitionnement.

Si vous souhaitez limiter les résultats de votre sampleQuery lorsque vous lisez des tables JDBC en parallèle, définissez le paramètre "sampleSize" plutôt que d'indiquer une clause LIMIT.

Exemple Utiliser SampleQuery avec le partitionnement JDBC

L'exemple de code suivant illustre comment utiliser sampleQuery avec partitionnement JDBC.

//note that the query should end with "where" or "and" if use with JDBC partitioning. val query = "select name from $tableName where age > 0 and" //Enable JDBC partitioning by setting hashfield. //to use sampleQuery with partitioning, set enablePartitioningForSampleQuery. //use sampleSize to limit the size of returned data. val connectionOptions = JsonOptions(Map( "url" -> url, "dbtable" -> tableName, "user" -> user, "password" -> password, "hashfield" -> primaryKey, "sampleQuery" -> query, "enablePartitioningForSampleQuery" -> true, "sampleSize" -> "1" )) val dyf = glueContext.getSource("mysql", connectionOptions) .getDynamicFrame()

Notes et restrictions :

Les exemples de requêtes ne peuvent pas être utilisés avec des signets de tâche. L'état du signet sera ignoré lorsque la configuration sera fournie pour les deux.

Utiliser un pilote JDBC personnalisé

Les exemples de code suivants montrent comment lire et écrire des bases de données JDBC avec des pilotes JDBC personnalisés. Ils présentent la lecture d'une version d'un produit de base de données et l'écriture dans une version ultérieure du même produit.

Python
import sys from awsglue.transforms import * from awsglue.utils import getResolvedOptions from pyspark.context import SparkContext, SparkConf from awsglue.context import GlueContext from awsglue.job import Job import time from pyspark.sql.types import StructType, StructField, IntegerType, StringType sc = SparkContext() glueContext = GlueContext(sc) spark = glueContext.spark_session # Construct JDBC connection options connection_mysql5_options = { "url": "jdbc:mysql://<jdbc-host-name>:3306/db", "dbtable": "test", "user": "admin", "password": "pwd"} connection_mysql8_options = { "url": "jdbc:mysql://<jdbc-host-name>:3306/db", "dbtable": "test", "user": "admin", "password": "pwd", "customJdbcDriverS3Path": "s3://DOC-EXAMPLE-BUCKET/mysql-connector-java-8.0.17.jar", "customJdbcDriverClassName": "com.mysql.cj.jdbc.Driver"} connection_oracle11_options = { "url": "jdbc:oracle:thin:@//<jdbc-host-name>:1521/ORCL", "dbtable": "test", "user": "admin", "password": "pwd"} connection_oracle18_options = { "url": "jdbc:oracle:thin:@//<jdbc-host-name>:1521/ORCL", "dbtable": "test", "user": "admin", "password": "pwd", "customJdbcDriverS3Path": "s3://DOC-EXAMPLE-BUCKET/ojdbc10.jar", "customJdbcDriverClassName": "oracle.jdbc.OracleDriver"} # Read from JDBC databases with custom driver df_mysql8 = glueContext.create_dynamic_frame.from_options(connection_type="mysql", connection_options=connection_mysql8_options) # Read DynamicFrame from MySQL 5 and write to MySQL 8 df_mysql5 = glueContext.create_dynamic_frame.from_options(connection_type="mysql", connection_options=connection_mysql5_options) glueContext.write_from_options(frame_or_dfc=df_mysql5, connection_type="mysql", connection_options=connection_mysql8_options) # Read DynamicFrame from Oracle 11 and write to Oracle 18 df_oracle11 = glueContext.create_dynamic_frame.from_options(connection_type="oracle", connection_options=connection_oracle11_options) glueContext.write_from_options(frame_or_dfc=df_oracle11, connection_type="oracle", connection_options=connection_oracle18_options)
Scala
import com.amazonaws.services.glue.GlueContext import com.amazonaws.services.glue.MappingSpec import com.amazonaws.services.glue.errors.CallSite import com.amazonaws.services.glue.util.GlueArgParser import com.amazonaws.services.glue.util.Job import com.amazonaws.services.glue.util.JsonOptions import com.amazonaws.services.glue.DynamicFrame import org.apache.spark.SparkContext import scala.collection.JavaConverters._ object GlueApp { val MYSQL_5_URI: String = "jdbc:mysql://<jdbc-host-name>:3306/db" val MYSQL_8_URI: String = "jdbc:mysql://<jdbc-host-name>:3306/db" val ORACLE_11_URI: String = "jdbc:oracle:thin:@//<jdbc-host-name>:1521/ORCL" val ORACLE_18_URI: String = "jdbc:oracle:thin:@//<jdbc-host-name>:1521/ORCL" // Construct JDBC connection options lazy val mysql5JsonOption = jsonOptions(MYSQL_5_URI) lazy val mysql8JsonOption = customJDBCDriverJsonOptions(MYSQL_8_URI, "s3://DOC-EXAMPLE-BUCKET/mysql-connector-java-8.0.17.jar", "com.mysql.cj.jdbc.Driver") lazy val oracle11JsonOption = jsonOptions(ORACLE_11_URI) lazy val oracle18JsonOption = customJDBCDriverJsonOptions(ORACLE_18_URI, "s3://DOC-EXAMPLE-BUCKET/ojdbc10.jar", "oracle.jdbc.OracleDriver") def main(sysArgs: Array[String]): Unit = { val spark: SparkContext = new SparkContext() val glueContext: GlueContext = new GlueContext(spark) val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray) Job.init(args("JOB_NAME"), glueContext, args.asJava) // Read from JDBC database with custom driver val df_mysql8: DynamicFrame = glueContext.getSource("mysql", mysql8JsonOption).getDynamicFrame() // Read DynamicFrame from MySQL 5 and write to MySQL 8 val df_mysql5: DynamicFrame = glueContext.getSource("mysql", mysql5JsonOption).getDynamicFrame() glueContext.getSink("mysql", mysql8JsonOption).writeDynamicFrame(df_mysql5) // Read DynamicFrame from Oracle 11 and write to Oracle 18 val df_oracle11: DynamicFrame = glueContext.getSource("oracle", oracle11JsonOption).getDynamicFrame() glueContext.getSink("oracle", oracle18JsonOption).writeDynamicFrame(df_oracle11) Job.commit() } private def jsonOptions(url: String): JsonOptions = { new JsonOptions( s"""{"url": "${url}", |"dbtable":"test", |"user": "admin", |"password": "pwd"}""".stripMargin) } private def customJDBCDriverJsonOptions(url: String, customJdbcDriverS3Path: String, customJdbcDriverClassName: String): JsonOptions = { new JsonOptions( s"""{"url": "${url}", |"dbtable":"test", |"user": "admin", |"password": "pwd", |"customJdbcDriverS3Path": "${customJdbcDriverS3Path}", |"customJdbcDriverClassName" : "${customJdbcDriverClassName}"}""".stripMargin) } }