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