En ocasiones tenemos datos relacionales que nos interesaría exportarlos a Hadoop para procesarlos, tratarlos o realizar algún cálculo determinado con ellos. En este post vamos a ver como podemos importar datos desde una base de datos relacional como es SQL Server 2012 a HDFS.

Vamos a utilizar una base de datos de ejemplo, Northwind. El motivo de elegir esta base de datos es porque las tablas utilizan el esquema dbo. Y qué ocurre con esto? El conector JDBC de SQL Server, presenta una limitación, y es qué no permite trabajar con tablas que utilicen esquemas personalizados. Os muestro un breve ejemplo. Tenemos en el servidor la base de datos de Adventure Works 2012, con diferentes esquemas, Person, Sales, Human Resources, etc. Vamos a ejecutar la siguiente sentencia en Sqoop, para mostrar un listado de las tablas de la base de datos AdventureWorks 2012. Recordad, sustituir SERVERNAME por el nombre de vuestro servidor e INSTANCENAME por el nombre de vuestra instancia de SQL Server.

sqoop list-tables --connect "jdbc:sqlserver://SERVERNAMEINSTANCENAME:1433;database=AdventureWorks2012;integratedSecurity=true"
Imagen 1: list-tables AdventureWorks 2012

Imagen 1: list-tables AdventureWorks 2012

Como se ve en la Imagen 1, tenemos en la imagen de fondo SQL Server Management Studio con la base de datos de Adventure Works 2012 y en el centro la línea de comandos de Hadoop con la sentencia ejecutada. Después de ejecutar la sentencia en Sqoop, sólo nos muestra las tablas cuyo esquema es dbo. Es algo que debemos tener en cuenta a la hora de trabajar con Sqoop, esperando que en la próxima versión del conector JDBC este problema esté resuelto.

Por tanto con el fin de mostrar como importar datos a HDFS desde SQL Server, vamos a utilizar la base de datos de Northwind.

Sqoop list-tables

Antes de realizar la importación vamos a ver las tablas que contiene la base de datos de Northwind. La sentencia sería:

sqoop list-tables --connect "jdbc:sqlserver://SERVERNAMEINSTANCENAME:1433;integratedSecurity=true;database=northwind"

image_thumb_2_1EF79FB3

 

Sqoop import

La herramienta import obtiene una tabla específica desde RDBMS a HDFS. Cada fila se representa como un registro en HDFS, los registros se pueden guardar como archivos de texto, o en representación binaria como SequenceFiles. La sentencia sería

sqoop import --connect "jdbc:sqlserver://SERVERNAMEINSTANCENAME:1433;database=northwind;integratedSecurity=true" --table "Contacts" --target-dir "///user/hadoop/sqoop/contacts"

Las filas que se han importado se han guardado como ficheros de texto en HDFS. Abrir Hadoop Name Node Status, y click en Browse the filesystem –> user –> hadoop –> sqoop –> contacts

Cada uno de los part-m-0000x son ficheros que contienen los registros de la tabla que se ha importado. Se puede ver el contenido haciendo click sobre el mismo archivo o mediante consola de comandos con esta sentencia:

hadoop fs -cat /user/hadoop/sqoop/contacts/part-m-0000

En el ejemplo anterior estamos importando la tabla completa, pero ¿qué pasa si sólo queremos importar un determinado número de filas o aquellas que cumplan una condición? En las sentencias de Sqoop import debemos usar la cláusula WHERE.

Seleccionar filas a importar

Es posible que nos interese importar sólo un determinado número de filas o aquellas que cumplan una condición. Para ello, debemos utilizar el argumento WHERE en la sentencia de sqoop. Vamos a importar de la tabla Contacts de la base de datos Norhwind, aquellos cuya ciudad sea Madrid. La sentencia sería:

sqoop import --connect "jdbc:sqlserver://SERVERNAMEINSTANCENAME:1433;database=northwind;integratedSecurity=true" --table "Contacts" --where "City='Madrid'" --target-dir "///user/hadoop/sqoop/contactsMadrid"

Para comprobar el resultado de la sentencia, escribir:

hadoop fs -cat /user/hadoop/sqoop/contactsMadrid/part-m-0000

Sqoop import-all-tables

Tenemos también la opción de importar todas las tablas de la base de datos. La sentencia sería:

sqoop import-all-tables --connect "jdbc:sqlserver://SERVERNAMEINSTANCENAME:1433;database=northwind;integratedSecurity=true" --warehouse-dir "///user/hadoop/sqoop/northwind" -m 1

 

Cargas incrementales

Supongamos que queremos realizar una importación de una tabla que tiene nuevos registros, pero sólo queremos obtener los nuevos. Sqoop tiene la posibilidad de realizar cargas incrementales. En este ejemplo, supongamos que hemos importado de la tabla Contacts hasta el contact ID 10. Ahora vamos a importar el resto de registros de la tabla Contacts. Los argumentos para realizar la carga incremental son:

–check-column: especifica la columna que se tiene que examinar para realizar la carga.

— incremental: tenemos dos opciones append y lastmodified. Utilizamos append cuando agregamos filas que tienen un identificador de fila incremental. Utilizamos lastmodified cuando las filas en la tabla origen pueden ser actualizadas, y cada actualización establecerá una columna con el último valor y la actual hora.

–last-value: especificamos el valor del último registro de la columna que hemos especificado en –check-column.

Entonces, la sentencia sería:

sqoop import --connect "jdbc:sqlserver://SERVERNAMEINSTANCENAME:1433;database=northwind;integratedSecurity=true" --table "Contacts" --check-column ContactID --incremental append --last-value 10 --target-dir "///user/hadoop/sqoop/contactsincremental"

image_thumb_3_1EF79FB3

Si observáis el resultado veréis que se han importado 123 filas en total, ya que dicha tabla tiene 133 registros en total, pero hemos importado a partir del registro 10.

 

Post anteriores relacionados con Sqoop: