2015-07-10 8 views
9

Quindi sono riuscito a distribuire il nostro DACPAC schema via Octopus. Sto usando uno script Deploy.ps1 che interagisce con oggetti .Net proprio come descritto nell'articolo.Come acquisire l'output di DacSevices.Deploy?

Vorrei rendere più trasparente il processo di distribuzione includendo lo "output standard" ottenuto da sqlcmd nei nostri registri Octopus. Sto cercando i messaggi di modifica dello schema generati e tutti i messaggi di migrazione di migrazione personalizzati che i nostri sviluppatori hanno inserito negli script pre/post.

L'unica soluzione che posso pensare è generare prima lo script con i servizi DACPAC e quindi eseguirlo con sqlcmd.exe. Qualche idea?

risposta

19

Trovato la soluzione, la pubblicazione nel caso in cui qualcun altro attraversa questo. Devi semplicemente iscriverti al tuo DacService's Message event.

C# di esempio:

var services = new Microsoft.SqlServer.Dac.DacServices("data source=machinename;Database=ComicBookGuy;Trusted_connection=true"); 

var package = Microsoft.SqlServer.Dac.DacPackage.Load(@"C:\Database.dacpac"); 

var options = new Microsoft.SqlServer.Dac.DacDeployOptions(); 
options.DropObjectsNotInSource = true; 
options.SqlCommandVariableValues.Add("LoginName", "SomeFakeLogin"); 
options.SqlCommandVariableValues.Add("LoginPassword", "foobar!"); 

services.Message += (object sender, Microsoft.SqlServer.Dac.DacMessageEventArgs eventArgs) => Console.WriteLine(eventArgs.Message.Message); 

services.Deploy(package, "ComicBookGuy", true, options); 

PowerShell campione (eseguito dalla Polpo Tentacle):

# This script is run by Octopus on the tentacle 
$localDirectory = (Get-Location).Path 
$tagetServer = $OctopusParameters["SQL.TargetServer"] 
$databaseName = "ComicBookGuy" 

Add-Type -path "$localDirectory\lib\Microsoft.SqlServer.Dac.dll" 

$dacServices = New-Object Microsoft.SqlServer.Dac.DacServices ("data source=" + $tagetServer + ";Database=" + $databaseName + "; Trusted_connection=true") 
$dacpacFile = "$localDirectory\Content\Unity.Quotes.Database.dacpac" 

$dacPackage = [Microsoft.SqlServer.Dac.DacPackage]::Load($dacpacFile) 

$options = New-Object Microsoft.SqlServer.Dac.DacDeployOptions 
$options.SqlCommandVariableValues.Add("LoginName", $OctopusParameters["SQL.LoginName"]) 
$options.SqlCommandVariableValues.Add("LoginPassword", $OctopusParameters["SQL.LoginPassword"]) 
$options.DropObjectsNotInSource = $true 

Register-ObjectEvent -InputObject $dacServices -EventName "Message" -Action { Write-Host $EventArgs.Message.Message } | out-null 

$dacServices.Deploy($dacPackage, $databaseName, $true, $options) 

Nella versione PowerShell non ho potuto ottenere il "Add_EventName" a portata di mano stile di notifica dell'evento funzionante quindi ho dovuto usare il cmdlet clunky. Meh.

+0

ho appena provato e funziona come previsto utilizzando C# e montaggio DacPac. Bella risposta! – Raffaeu

+0

Vale la pena notare che Register-ObjectEvent funziona in modo asincrono, quindi lo script principale non aspetterà che la riga Register-ObjectEvent elabori tutti i messaggi e che possa finire prima di visualizzare tutti gli eventi. – Rod

0

Utilizzare sqlpackage anziché sqlcmd per distribuire dacpac.

ultima versione qui: https://msdn.microsoft.com/en-us/mt186501

$sqlpackage = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\120\sqlpackage.exe" 

Sarà errori di output automaticamente sulla console. Utilizziamo la definizione di build TFS e chiamiamo PowerShell ed è in grado di visualizzare gli errori accaduti durante una distribuzione.

Usage:

& $sqlpackage /Action:Publish /tsn:$dbServer /tdn:$database /sf:$mydacpac/pr:$dbProfile /variables:myVariable=1 
+1

Questa è un'alternativa intelligente Sono andato con la rotta API/PowerShell invece di chiamare un EXE perché richiedeva un insieme leggermente più piccolo di dipendenze ... anche se in retrospettiva la complessità aggiuntiva richiesta nello script supererebbe il fatto di avere l'EXE in giro. Grazie per l'input! –

+0

David, Yes API funziona bene anche. Lo usiamo quando eseguiamo uno script dal back-end, ma utilizziamo principalmente distribuzioni self-service in ambienti inferiori e le definizioni TFS Build sono in grado di catturare correttamente gli errori. Eseguire EXE direttamente da PowerShell non fa un buon lavoro. – Vinnie