Cómo automatizar la codificación y envío por lotes de objetos SQL al control de versiones

Muchos equipos de desarrollo tienen la necesidad de una solución rápida pero efectiva para enviar objetos de bases de datos SQL Server al control de versiones, pero no están listos para moverse a una integración total.

Para que los objetos estén bajo el control de versiones en un enfoque “económico”, scripts de creación necesitan ser producidos para cada tabla, procedimiento almacenado, o cualquier otro objeto en la base de datos. Después, los scripts necesitan ser enviados a un sistema de control de versiones.

Examinaremos los dos enfoques. Un enfoque codificado personalizado usando PowerShell para codificar objetos en scripts DDL individuales y luego cargarlos a un control de versiones, y una solución de terceros que se especializa en codificación y carga de objetos a controles de versión.

Usando un proyecto PowerShell y un archivo de lotes

Una manera de automatizar el proceso de enviar objetos SQL a un sistema de control de versiones es:

  1. Cree un proyecto PowerShell que codificará los objetos SQL deseados en la base de datos:

    $ServerName='CRaZY' # enter the name of a server
    $Database='ObjectScripting' # enter the name of a database
    $DirectoryToSaveTo='D:\SC\ScriptObject' # enter the directory where to store SQL scripts for objects
    # load SMO assembly, and if SQL 2008 DLLs are run, load the SMOExtended and SQLWMIManagement libraries
    $v = [System.Reflection.Assembly]::LoadWithPartialName( 'Microsoft.SqlServer.SMO')
    if ((($v.FullName.Split(','))[1].Split('='))[1].Split('.')[0] -ne '9') {
        [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMOExtended') | out-null
    }
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SmoEnum') | out-null
    set-psdebug -strict # catch a few extra bugs
    $ErrorActionPreference = "stop"
    $My='Microsoft.SqlServer.Management.Smo'
    $srv = new-object ("$My.Server") $ServerName # Attach to the server
    if ($srv.ServerType-eq $null) # If it managed to find a server
                    {
       Write-Error "Sorry, but I couldn't find Server '$ServerName' "
       return                
    } 
    $scripter = new-object ("$My.Scripter") $srv # create the scripter
    $scripter.Options.ToFileOnly = $true 
    # first we get the bitmap of all the object types we want 
    $all =[long] [Microsoft.SqlServer.Management.Smo.DatabaseObjectTypes]::all
    # and we store them in a datatable
    $d = new-object System.Data.Datatable
    # get everything except the servicebroker object, the information schema and system views
    $d=$srv.databases[$Database].EnumObjects([long]0x1FFFFFFF -band $all) | `
        Where-Object {$_.Schema -ne 'sys'-and $_.Schema -ne "information_schema" -and $_.DatabaseObjectTypes -ne 'ServiceBroker'}
    # and write out each scriptable object as a file in the directory you specify
    $d| FOREACH-OBJECT { # for every object we have in the datatable.
                    $SavePath="$($DirectoryToSaveTo)\$($_.DatabaseObjectTypes)"
                    # create the directory if necessary (SMO doesn't)
                    if (!( Test-Path -path $SavePath )) # create it if not existing
                        {Try { New-Item $SavePath -type directory | out-null } 
                     Catch [system.exception]{
                        Write-Error "error while creating '$SavePath' $_"
                         return
                      } 
                    }
                    
                    $scripter.Options.Filename = "$SavePath\$($_.name -replace '[\\\/\:\.]','-').sql";
                    # Create a single element URN array
        $UrnCollection = new-object ('Microsoft.SqlServer.Management.Smo.urnCollection')
                    $URNCollection.add($_.urn)
                    # and write out the object to the specified file
        $scripter.script($URNCollection)
    } 
  2. Grabe el siguiente código como un archivo de lotes para enviar los objetos codificados SQL al control de versiones como un archivo de lotes:

    @echo off
    Powershell.exe -executionpolicy remotesigned -File D:\SC\ScriptObject\PSscript\Script.ps1
    timeout 10
    cd D:\SC\ScriptObject
    %ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe add 
    D:\SC\ScriptObject>tf checkin /noprompt
    
  3. Enviar objetos SQL codificados con ApexSQL Script

    ApexSQL Script es una herramienta de codificación SQL que permite codificar objetos de bases de datos SQL y enviar scripts SQL a controles de versiones. Puede exportar bases de datos directamente a controles de versión y puede automatizar la codificación SQL y programar el proceso de migración sin la atención de un usuario.

    ApexSQL Script también permite codificar cada objeto SQL a un archivo .sql individual y enviarlos al control de versiones:

    1. Inicie ApexSQL Script
    2. En la ventana New Project, elija el servidor y una manera de autenticación, haga clic en el botón Connect para conectarse a un servidor y seleccione una base de datos:

    3. En el diálogo Project, haga clic en el botón Show advanced options y seleccione la pestaña Object filter:

    4. Por defecto, todos los objetos son seleccionados para el proceso de codificación. Pero si hay la necesidad de seleccionar algunos objetos particulares, haga clic en la casilla Filter para un tipo deseado de objeto, y seleccione el nodo de ese tipo de objeto en la ventana Select object types to script:

    5. Seleccione todos los objetos que desea incluir en el proceso de codificación:

    6. Una vez que todo esté configurado, haga clic en el botón Open en la esquina inferior derecha, en la ventana New Project, para cargar los objetos de base de datos:

    7. Debajo de la vista Structure, seleccione los objetos para enviar al control de versiones y haga clic en el botón Script desde la pestaña Home para iniciar el proceso de codificación:

    8. En el primer paso del proceso de la codificación, seleccione el modo de codificación y el tipo de salida:

    9. El segundo paso permite la codificación de objetos dependientes, si es necesario:

    10. En el siguiente paso, elija la acción Create and commit to source control desde la lista desplegable Action, y haga clic en el botón Edit para configurar los ajustes del control de versiones. Por favor, note que el repositorio del control de versiones necesita ser creado antes de proceder, y más acerca de eso puede ser encontrado aqui.

    11. En Source control wizard, elija el sistema de control de versiones y haga clic en el botón Next:

    12. Establezca la información de inicio de sesión para el sistema de control de versiones y haga clic en el botón Finish:

    13. Después de configurar el control de versiones, haga clic en la pestaña Script file y seleccione la opción Script each object into an individual file desde la lista desplegable Granularity:

    14. Haga clic en el botón Next y el paso Export batch será mostrado:

      En el panel Batch script, todos los ajustes del proyecto actual son “traducidos” a interruptores CLI. Para tener menos interruptores CLI, todos ellos pueden ser reemplazados con el interruptor del proyecto ( /pr), seleccionando la opción Use project file en la esquina inferior izquierda:

      Para usarlo en el proceso automatizado, haga clic en el botón Save as batch y el archivo del proyecto, junto con el archivo de lotes, serán grabados en la localización provista.

    15. Haga clic en el botón Create para comenzar a enviar los scripts al control de versiones.

    16. Después de que el proceso finalice, los resultados son mostrados en la siguiente ventana:

    Automatizando el proceso con la Interfaz de Línea de Comandos (CLI) de ApexSQL Script

    La otra manera de realizar el envío de scripts individuales a un repositorio de control de versiones es usando la Interfaz de Línea de Comandos (CLI) de ApexSQL Script. La manera más fácil es grabar el archivo del proyecto, como en el paso 14, porque es más fácil establecer todos los ajustes en la Interfaz Gráfica que añadir interruptores para cada opción en la CLI.

    Después de grabar el archivo del proyecto, llámelo desde la CLI y añada el resto de los interruptores opcionales, para enviar los scripts al control de versiones:

    “ApexSQLScript.com” # application path
    /pr:”MyProject.axsc” # ruta del archive del proyecto
    /v # imprime todos los mensajes en la consola
    /f # sobrescribe los archivos de script existentes
    /out:”Output.txt” # redirecciona la salida de la consola a un archive especificado
    @echo ApexSQL Script return code is %errorlevel% >> /out:”Output.txt” # código de retorno al finalizar el proceso de codificación

    Todos los interruptores CLI de ApexSQL Script son explicados en el artículo en este enlace, junto con algunos ejemplos.

    Si hay la necesidad de permitir el pedido de credenciales de la base de datos/inicio de sesión, revise el artículo en este enlace para información acerca de cómo lograrlo.

    julio 22, 2017