Vous êtes sur la page 1sur 9

thesolidqjournal business intelligence

Por Enrique Catala

16

Generacin de paquetes SSIS programticamente (Parte I)


Existe un viejo adagio que dice que cuando necesites escribir cdigo, deberas considerar en su lugar escribir cdigo que generase cdigo. Los usuarios experimentados de SSIS generan paquetes repetitivos programticamente y de esa forma, aprenden a regenerarlos rpidamente cuando surge la necesidad de un cambio. Este artculo es la primera parte de una corta serie que le mostrar cmo crear paquetes SSIS mediante programacin.
Introduccin

egn la tendencia que hemos detectado por el tipo de proyectos que llevamos a cabo y que queda contrastado en peridicos digitales como Finanzas.com, una de las profesiones ms demandadas tanto actualmente como en un futuro inmediato es la consultora avanzada en inteligencia de negocio. Parece claro por tanto, que disponer de herramientas potentes, sencillas y fcilmente amoldables a nuestros requerimientos cambiantes va a propiciar un auge en la calidad de nuestros servicios. Como cualquier lector sabe, Solid Quality Mentors es el lder de soluciones global en tecnologa Microsoft de la plataforma de datos, plataforma de datos que nos provee de entre otras herramientas y tecnologas, las que vamos a discutir en este artculo: SQL Server Integration Services (a partir de ahora nos referiremos a l como SSIS). Como sabemos, todo proyecto de inteligencia de negocio lleva consigo irremediablemente la consolidacin de informacin eficiente. Dicho proceso de consolidacin se consigue con SSIS y su diseo es tan personalizado como potencialmente similar en todos los escenarios en los que hemos trabajado, que es una buena idea el automatizar su creacin. Desde SolidQ nos hemos percatado que en muchas ocasiones el cliente duplica bases de datos con la

misma estructura para proporcionar lo que ellos denominan particiones, que no es ms que un tipo de Sharding manual, o directamente tablas renombrndolas para tratar de conseguir particionado. Todo esto, no hace ms que aadir complejidad al proceso de creacin del Datawarehouse, que es donde debe residir la informacin unificada y limpia para poder explotarla correctamente. Adems de dicha complejidad aadida, en la ejecucin de un proyecto de inteligencia de negocios en la que se involucran la creacin de paquetes SSIS, se da la circunstancia que por tratarse de proyectos vivos y tpicamente de media duracin, los objetos fuente (tablas) en ocasiones son modificados para aadir columnas, cambiar tipos de datos, eliminar columnas,con lo que en ocasiones obliga a rehacer trabajo en SSIS que como sabemos es fuertemente tipado. En este artculo sentaremos las bases para poder entender cmo crear paquetes SSIS con los que conseguir que fcilmente podamos unificar toda la informacin a base prcticamente de 2 clics de ratnJ. Adems, gracias a que utilizando dichas libreras no realizaremos intervencin humana directa en la creacin del paquete SSIS, un cambio en los objetos fuente o destino de nuestros paquetes, solo requerirn darle de nuevo al botn generar de nuestro generador J. Por mi experiencia, si nuestro sistema pasa de las 50 o

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

17

60 tablas ya se ahorra tiempo hacindolo de esta forma si tenemos que repetir el proceso solamente una vez porque al final nos damos cuenta de un detalle (pequeo o no) con la mitad de las tablas ya habramos ahorrado tiempo escribiendo este cdigo. En resumen lo que vamos a ver es como crear una aplicacin de Consola C# que va a generar paquetes de SSIS sin intervencin humana (obviamente en algun momento le tendremos que indicar el origen y el destino, pero nada ms).

Figura 0

Requisitos para reproducir el artculo


Para la reproduccin del artculo se recomienda disponer de los siguientes requisitos: Visual Studio 2010: La versin Express debera ser suficiente SQL Server 2008 R2 (como mnimo ser necesario versin standard para disponer de SSIS y probar nuestros paquetes generados) Conocimientos de SSIS: Se parte de la base de que el lector conoce como crear paquetes SSIS, desplegarlos y utilizarlos. Conocimientos altos en programacin C# y manejo de Visual Studio 2010 Se parte de la base de que el lector conoce metodologas de programacin orientadas a objetos y posee conocimientos en el manejo de Visual Studio 2010 Adicionalmente, en el site de solidq, puedes encontrar el cdigo de la solucin para descarga. Pincha aqu.

Figura 1 macin necesaria para que el proceso dtexec.exe sea capaz de realizar lo que hemos indicado en l. Para nuestro ejemplo usaremos la BBDD AdventureWorks y lo que haremos ser mover informacin a una BBDD nueva a la que llamaremos Staging.

El paquete dtsx
Antes de nada, hay que tener claro que el proceso de generacin por cdigo de paquetes SSIS no est bien documentado, por lo que mucho de lo que aqu vas a leer proviene tanto de prueba-error, como de ingeniera inversa analizando el comportamiento de objetos y el xml resultante. Con ello no quiero decir que haya violado ningn copyright, simplemente estoy diciendo que para saber cmo funciona correctamente un mtodo, en ocasiones he tenido que ver qu generaba y compararlo con uno que haba generado mediante la interfaz de Visual Studio. Recuerda adems, que un paquete de integration services, no es ms que un XML que contiene la meta infor-

Figura 2

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

thesolidqjournal business intelligence

18

Qu pretendemos obtener?
Lo primero que recomiendo al lector, es que tenga claro lo que pretende obtener, y la mejor manera de hacerlo es realizando el paquete mediante la herramienta destinada para ello, Visual Studio. Una vez se tenga claro lo que se desea obtener, podremos entonces plantear darle una solucin por cdigo. Se sobreentiende por tanto, que el lector plantea realizar n paquetes idnticos en los que cambie alguna particularidad. Por experiencia, es un escenario muy comn. Para este primer artculo, vamos a empezar con un cdigo de lo ms sencillo, para ir entrando las bases de lo que implica codificar SSIS programticamente. Por tanto, el ejemplo ms sencillo que se me ha ocurrido es simplemente mover datos de una tabla origen a una tabla destino.

Pero previamente a ello, lo normal es que aadamos nuestros objetos conexin, tal y como podemos ver en la Imagen 0, pgina 17. En la configuracin del OleDbSource, indicaramos qu objeto queremos como fuente (Imagen 3) y en OleDbDestination indicaramos qu objeto queremos como destino (Imagen 4) En resumen, mover los datos de la tabla HumanResources.Employee de la BBDD Adventureworks, a la tabla dbo.employee de la BBDD Staging. NOTA: El nico requisito de momento es que la tabla destino, a la que nosotros referenciamos como employee, debe existir.

Creacin del paquete programticamente


Para la construccin de nuestro generador de SSIS, vamos a optar por utilizar Visual Studio 2010. Esto igual te llama la atencin, ya que la edicin Visual Studio 2008 es la edicin habilitada para crear paquetes SSIS.

Figura 3

Figura 5 Figura 4 Para conseguir esto, si estuviramos utilizando el modelador de SSIS, deberemos aadir un componente DataFlow tal y como se puede apreciar en la Imagen 1, pgina 17, y dentro de ella, dos componentes OleDbSource y OleDbDestination. No obstante, en nuestro caso lo que vamos a hacer es utilizar las libreras que finalmente utiliza Visual Studio 2008, por lo que es indiferente el entorno de desarrollo utilizado, puesto que nosotros vamos a construirnos nuestro propio generador de SSIS. Lo primero que debemos hacer es crearnos una solucin que constar de:

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

19

Aadir componentes Data Flow

Figura 6 Proyecto de librera (EnriqueCatalaSSISGenerator): Contendr el cdigo del generador de SSIS. Proyecto de consola (DemoSSISGenerator): Se encargar de utilizar el proyecto de librera para crear el paquete. Lo siguiente ser aadir las libreras necesarias para la elaboracin de la librera del generador de SSIS. Dichas libreras se encuentran dentro de la carpeta SDK de Microsoft SQL Server y son las que se pueden apreciar en la imagen 6. C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies: Una vez hecho esto, nos pondremos manos a la obra para la codificacin de los mtodos necesarios para nuestro Generador de cdigo SSIS. NOTA: Recuerda que puedes descargar la solucin de aqui. Aadir componentes OleDbSource

Aadir componentes OleDbDestination

Librera de generacin de cdigo SSIS


Visto el tipo de paquete SSIS que queremos modelar, nos debemos poner manos a la obra para la codificacin de los mtodos necesarios, que deben cubrir los siguientes escenarios: Aadir objetos conexin OLEDB

Mtodo principal de generacin de paquete que utilice los anteriores

Aadir objetos conexin OLEDB


Para aadir una conexin OleDb a un paquete SSIS, lo nico que debemos hacer es crear un objeto de la clase ConnectionManager, instanciando sus propiedades ConnectionString y Name. Mientras que ConnectionString identificar una cadena de conexin vlida, la propiedad Name, identificar el nombre de la conexin tal y como la vemos en el paquete al editarlo.

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

thesolidqjournal business intelligence

20

El cdigo necesario para aadir conexiones OleDb a nuestros paquetes por cdigo ser este:

Finalmente, debemos indicar en sus propiedades que ser AccessMode = 0 y que el tipo OpenRow-

Listado 1

protected ConnectionManager AddOleDbConnection(Package pck,string nameConexion,string CadenaConexion) { ConnectionManager cm; cm=pck.Connections.Add(OLEDB); cm.ConnectionString=CadenaConexion; cm.Name=nameConexion; return (cm); }

Aadir componentes DataFlow


Aadir componentes dataflow requiere aadir al conjunto de Executables del objeto Package, un tipo de ejecutable denominado STOCK:PipelineTask.

set debe apuntar al nombre de tabla con esquema que le hayamos pasado (recuerda, en nuestro ejemplo ser HumanResources.Employee. Finalmente, inicializaremos sus metadatos (ver cdigo try). Esta ltima parte, abrir conexin contra

Listado 2
protected virtual TaskHost AddDataFlow(Package pck,string dataFlowName) { Executable e=pck.Executables.Add(STOCK:PipelineTask); TaskHost thMainPipe=(TaskHost)e; thMainPipe.Name=dataFlowName; return (thMainPipe); }

Aadir componentes OleDbSource


Si recordamos, en el escenario que queremos modelar, estamos tomando datos directamente desde una tabla, identificndola nicamente por su nombre (no hemos especificado ninguna select). Lo primero que debemos hacer es crear un objeto estndar IDTSComponentMetaData100 que identificar nuestro objeto conexin (al origen, recuerda). Luego, ese componente, como queremos que sea un OleDbSource, lo identificaremos en su propiedad ComponentClassID indicando el valor DTSAdapter.OLEDBSource. Una vez hecho eso, lanzaremos el mtodo Instantiate() y ProvideComponentProperties() para que el objeto adquiera sus propiedades de OleDBSource.

SQL Server e intentar inicializarlos, si por lo que sea hemos proporcionado mal el objeto connection, nos dar error aqu. Ver listado 3, pgina 21.

Aadir componentes OleDbDestination


En este momento, nos queda proporcionar el cdigo que identifique al componente OleDbDestination. A diferencia del anterior mtodo, en este caso no solo necesitaremos proporcionar un objeto conexin hacia destino y un nombre de tablaen este caso, necesitaremos proporcionarle un componente origen (recuerda que en este caso, vamos a conectar directamente el componente OleDbSource al OleDbDestination.

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

21

Listado 3
protected virtual IDTSComponentMetaData100 AddSourceOleDbFromTable(PWrap.MainPipe flujo,string nombreComponente,string no mbreTablaConEsquema,ConnectionManager connection) { PWrap.IDTSComponentMetaData100 conexionAOrigen=flujo.ComponentMetaDataCollection.New(); conexionAOrigen.Name=nombreComponente; conexionAOrigen.ComponentClassID=DTSAdapter.OLEDBSource; PWrap.CManagedComponentWrapper instance=conexionAOrigen.Instantiate(); instance.ProvideComponentProperties(); conexionAOrigen.RuntimeConnectionCollection[0].ConnectionManager=DtsConvert.GetExtendedInterface(connection); conexionAOrigen.RuntimeConnectionCollection[0].ConnectionManagerID=connection.ID; conexionAOrigen.Name=nombreComponente; instance.SetComponentProperty(AccessMode,0); instance.SetComponentProperty(OpenRowset,nombreTablaConEsquema); //Reinitmetadata try { instance.AcquireConnections(null); instance.ReinitializeMetaData(); instance.ReleaseConnections(); } catch (Exception e) { throw ; } return (conexionAOrigen); }

Ahora, las propiedades asignadas sern: AccessMode = 3 (carga identificando un nombre de objeto) FastLoadOptions = TABLOCK, CHECK_CONSTRAINTS (queremos carga rpida) OpenRowset = nombre de objeto destino (en este caso dbo.employee). Una vez indicadas las propiedades, en el bucle foreach que se aprecia en el cdigo, mapearemos las columnas del componente OleDbSource a este componente recientemente creado. Ver listaddo 4, pgina 22.

Al igual que antes, el cdigo de inicializacin es muy similar, y solo va a cambiar: ComponentClassID valdr DTSAdapter.OleDbDestination puesto que queremos un objeto de tipo destino

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

thesolidqjournal business intelligence

22

Listado 4

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

23

Generacin del paquete


Una vez dispuestos del cdigo anterior, nicamente debemos utilizar los mtodos creados anteriormente para generar nuestro paquete. Esto es tan fcil como lo que veis en el cdigo siguiente. Ver listado 5.

Proyecto de consola
Ya por ltimo, en nuestra aplicacin de consola, solo nos queda instanciar un objeto de nuestra clase generadora de cdigo y proporcionarle los valores que queramos. Ver listado 6, pgina 24. El resultado de su ejecucin puede verse aqu (despus de abierto y lanzado el paquete.dtsx)

Listado 5

public void GeneratePackage(string sourceConnectionString,string destinationConnectionString) { /// Openconnectiontosource /// OleDbConnection cn=new OleDbConnection(sourceConnectionString); cn.Open(); /// Packagecreation Package Mipk=new Package(); ///Wecanspecifyapackagename(optional) Mipk.Name=PackageName ; Applicationapp=newApplication(); ///SourceOleDbconnection ConnectionManager connOrigen=AddOleDbConnection(Mipk,ORIGEN,sourceConnectionString); ///DestinationOleDbconnection ConnectionManager connDestino=AddOleDbConnection(Mipk,DESTINO,destinationConnectionString); //AddDataFlow PWrap.MainPipe df=AddDataFlow(Mipk,SolidQJDataflow).InnerObjectas MainPipe; ///AddSourceoledbconnector IDTSComponentMetaData100 source=AddSourceOleDbFromTable(df,Sourcecomponent,humanresources.employee,connOrigen); ///Adddestinationoledbconnector AddOleDbDestinationTable(df,connDestino,source,dbo.Employee); ///Savethefiletofolder app.SaveToXml(@c:\bbdd\package.dtsx,Mipk,null); }

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

thesolidqjournal business intelligence

24

Listado 6
static void Main(string[]args) { EnriqueCatalaSSISGenerator.EnriqueCatalaSSIS packageGenerator=new EnriqueCatalaSSISGenerator.EnriqueCatalaSSIS(); String destinationCS=@DataSource=(local)\sql2008r2;InitialCatalog=Staging;Provider=SQLNCLI10.1;IntegratedS ecurity=SSPI;ApplicationName=SSIS-Package;AutoTranslate=False;; String sourceCS=@DataSource=(local)\sql2008r2;InitialCatalog=AdventureWorks;Provider=SQLNCLI10.1;IntegratedSecurity=SSPI;ApplicationName=SSIS-Package;AutoTranslate=False;; packageGenerator.GeneratePackage(sourceCS,destinationCS); }

Conclusin
Como se ha podido ver, el proceso de generacin mediante cdigo de SSIS es una tarea relativamente sencilla si se conocen los aspectos bsicos de la misma. No obstante, su codificacin entraa la necesidad de conocer por dentro las clases de generacin de componentes y objetos, que por otro lado no hemos entrado en mucho detalle por tratarse de un primer artculo y no quiero asustar al lector con detalles demasiado profundos. La idea final es acabar generando paquetes ms complejos, como los que se pueden ver en la siguiente imagen, que poseen flujos variables y componentes ms complejos con operadores Merge Join o el temido Conditional Split que tantas horas nos hacen pasar delante a la hora de su configuracinJ. Gracias a una librera como la que disponemos en SolidQ y que queremos dar una idea de su construccin al lector, desde Solid Quality Mentors, podemos generar miles de paquetes que realicen tareas real-

mente complejas en tan solo unos segundos, y lo que es mas importanteun cambio en los objetos inherentes al paquete (cambios de tipos de datos, nombres de columnas, de objetosno tienen ningn coste alguno puesto que regenerar el paquete es cuestin de dos clics de ratnJ. En siguientes artculos, veremos como seremos capaces de que incluso estos operadores sean capaces de inferir columnas y tipos de datos complejos sin intervencin humana. Aqu tenemos unas muestras de los tipos de paquete que genera el generador de SSIS de solidq sin intervencin humana. Ver Figura 7.

Acerca del Autor


Enrique Catal Bauls pertenece al rea relacional de SolidQ. Es MCT, MCITP, MCTS y ha sido nombrado MAP 2010 (Microsoft Active Professional). Es arquitecto y programador de la solucin HealthCheck, SCODA, SolidQDataCollector y el SolidQ SSIS Generator. En los pasados 5 aos mientras se centraba en las bases de datos SQL Server aportaba soluciones a problemas relacionados con el rendimiento, la escalabilidad, las migraciones y la alta disponibilidad. Adems de impartir cursos oficiales de Microsoft, ha tomado parte como ponente en el lanzamiento Microsoft SQL Server 2008) en el 24h SQL PASS Conference, y como miembro del nuevo SQL PASS Spain, tambin ha impartido charlas a grupos de usuarios de Microsoft GuseNET. Tambin es ponente habitual en SolidQ Summit Madrid.

Figura 7

The SolidQ Journal, Abril 2011 www.solidq.com/sqj

Vous aimerez peut-être aussi