En ingeniería de software, hace bastantes años que Microsoft nos hizo un gran aporte con las herramientas de gestion de proyectos de base de datos a través de Visual Studio. Gracias a ello, los administradores y desarrolladores de BBDD podemos utilizar Visual Studio para gestionar el ciclo de vida de las BBDD en entornos corporativos, permitiéndonos hacer el mismo seguimiento y evolución con nuestras BBDD al que están acostumbrados los equipos de desarrollo cuando hablamos de aplicaciones. Ya sabes…integración continua, despliegues con tests unitarios,….
Al hilo de esto, en un proyecto bastante grande en el que estoy metido últimamente ha surgido la necesidad de generar automáticamente ciertas partes de código, y dado que es un proyecto siguiendo una metodología de desarrollo Agil con Scrum y Visual Studio con proyectos de BBDD, he podido aprovechar una de las características que siempre me han gustado mas de Visual Studio…las plantillas de generación de código T4.
Imagínate que tienes una BBDD con 11.000 objetos, siendo por ejemplo 5.000 tablas sobre las que quieres añadir un sistema de auditoria a base de triggers DML (no entraré en por qué necesitas eso, solo que quieres hacerlo). En una situación así tienes 2 opciones:
- Te pones en modo monkey y te codificas a mano el sistema de auditoria para las 5000 tablas (con sus triggers, sus tablas de histórico, sus procedimientos de extracción…)
- Te pones a pensar un poco y programas un sistema que automatice el proceso.
Obviamente nadie en sus cabales optaría por la opción 1, asique asumiendo que optamos por la opción 2, tenemos múltiples opciones, siendo las 3 típicas:
- Nos programamos un procedimiento almacenado en la BBDD que cuando lo llamemos, nos genere los create tables, create triggers,…
- Nos programamos un .exe, un powershell…que cuando lo ejecutemos nos genere los create tables, create triggers,…y que o bien nos genere los .SQL o bien nos actualice directamente la BBDD (riesgo máximo :)).
- Utilizamos los proyectos de BBDD y nos creamos una plantilla de generación de código T4 y nos generamos los create tables, create triggers…
Obviamente las 3 opciones son válidas y las dos primeras son las que siempre me acabo encontrando. En este post voy a defender mi opción preferida como no podía ser de otra forma, y espero que te sirva para darte un punto de vista nuevo a ti también a la hora de valorar una posible solución a un caso como este.
Por qué utilizar plantillas T4?
T4 es la abreviatura de “Text Template Transformation Toolkit” y es una tecnología ampliamente adoptada por desarrolladores desde hace más de 10 años; No son un recurso exclusivo como digo de proyectos de BBDD y sí que son un recurso utilizado por proyectos de software mediante Visual Studio desde su versión 2005 (no se trata de algo novedoso ni mucho menos)…La ventaja de este sistema aplicado un proyecto de BBDD son principalmente:
- Te permite generar múltiples objetos dentro de tu propio proyecto de BBDD
- Se integra con tu propio sistema de control de código fuente (se genera un .SQL que estará vinculado a tu sistema de control de versiones)
- Se crea como un recurso más, y por tanto se compila junto al resto de tu solución
- Se actualiza de forma transparente (si quieres) para poder despreocuparte de tu código generado
Suponiendo que queramos aprender a utilizarlas, tenemos básicamente 2 opciones:
- Generar una plantilla t4 con código ADO.NET que vaya realizando queries al catálogo de SQL Server para ir materializando lo que queramos
- Utilizar el framework DACFx para ir realizando queries al contenido in-memory de nuestro propio proyecto de base de datos (SSDT)
La opción 1 es la que vas a encontrarte siempre por ahi y obviamente no está mal, pero a pesar de que obviamente tiene los beneficios que he comentado antes, tiene una pega muy grande…necesitas conectividad a la BBDD sobre la que quieras generar código, por lo que tienes que desplegar cambios antes de poder generar tu código sobre ellos en una especie de círculo dependiente absurdo y poco útil en un entorno real. Llegados a este punto, cualquiera que se haya querido poner con esto, ha visto más práctico optar por generarse su propio .exe y bueno…ha descartado por siempre el uso de t4…hasta ahora 🙂
Cómo generar código T-SQL a partir de nuestro modelo SSDT
En relación a lo que te acabo de comentar, he ralizado una mejora bastante interesante a un proyecto existente que comenzó el año pasado de forma básica a permitir trabajar con este sistema. Se trata del proyecto “T4 Template to auto-generate T-SQL from SSDT“.
[box type=”info”] Gracias al proyecto https://t4dacfx2tsql.codeplex.com/ podrás generar código T-SQL de forma realmente sencilla sobre tus proyectos de base de datos[/box]Para utilizarlo en tu proyecto es tan sencillo como copiarte el fichero “InmemoryDatabaseModelInclude.tt” que hay publicado en el citado proyecto y añadirte entonces tu fichero de generación:
Y luego, en el fichero generado, poner como primera línea una referencia al modelo:
A partir de ahi…pues generar el código que necesites para obtener tu script .SQL…
Qué es lo que he añadido al proyecto y que considero que lo hacen apto para que lo tengas en cuenta?
- Puedes filtrar mediante JSON qué objetos de tu modelo cargar en memoria DACFx para así poder disminuir drásticamente el tiempo de generación de código en proyectos realmente grandes
- En el proyecto de 11.000 objetos se pasa de 10m de generación de triggers, a 5 segundos!
- Es compatible con Visual Studio 2015 y SQL Server 2014 y 2016
- Ya no necesitas tener VS2012! 🙂
Te dejo aquí un ejemplo de plantilla T4 que genera tablas y triggers de auditoria sobre un proyecto SSDT
2 comments
Hola Enrique! Muy útil post gracias por compartir! Definitivamente voy a probar esto, anteriormente estuve usando un proyecto tmb de t4 para precargar algunas tablas en un proyecto de SSDT… Me ahorre un montón de trabajo, dejó el Link http://www.jorriss.net/2015/12/07/visual-studio-database-projects-and-the-problem-with-reference-data-part-two/
Para hacer frente a este problema usaste algún enfoque similar en el proyecto en el q estas trabajando? De nuevo gracias!
Pues la verdad que lo que comentas no se me ha dado el caso todavía de hacerlo, pero definitivamente lo miraré a ver. Un saludo