2015-07-10 14 views
9

So habe ich es geschafft, unsere DACPAC schema via Octopus bereitzustellen. Ich verwende ein Deploy.ps1-Skript, das mit .NET-Objekten interagiert, genau wie im Artikel beschrieben.Wie DacSevices.Deploy Ausgabe erfassen?

Ich möchte den Bereitstellungsprozess transparenter machen, indem Sie die "Standardausgabe", die Sie von sqlcmd erhalten, in unsere Octopus-Protokolle aufnehmen. Ich suche nach den generierten Schemamodifizierungsnachrichten sowie nach benutzerdefinierten Migrationsmigrationsnachrichten, die unsere Entwickler in die Pre-/Post-Skripts eingegeben haben.

Die einzige Problemumgehung, die ich mir vorstellen kann, besteht darin, zuerst das Skript mit den DACPAC-Diensten zu generieren und es dann mit sqlcmd.exe auszuführen. Irgendwelche Ideen?

Antwort

19

Gefunden die Lösung, Buchung für den Fall, dass jemand anderes über diese läuft. Sie müssen nur die Message event Ihres DacServices abonnieren.

C# Beispiel:

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 Probe (von der Octopus Tentacle ausgeführt):

# 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) 

In der Powershell-Version konnte ich nicht das handliche "Add_EventName" bekommen Stil der Ereignisbenachrichtigung funktioniert, also musste ich das klobige Cmdlet verwenden. Meh.

+0

ich gerade versucht, und es funktioniert wie C# und DacPac Montag erwartet werden. Gute Antwort! – Raffaeu

+0

Beachten Sie, dass Register-ObjectEvent asynchron arbeitet. Daher wartet das Hauptskript nicht auf die Register-ObjectEvent-Zeile, um alle Nachrichten zu verarbeiten, und beendet möglicherweise, bevor alle Ereignisse angezeigt werden. – Rod

0

Verwenden Sie sqlpackage anstelle von sqlcmd, um dacpac zu implementieren.

Get Latest Version hier: 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" 

Es wird automatisch Ausgabefehler auf der Konsole. Wir verwenden die TFS-Builddefinition und Call-Powershell und können Fehler anzeigen, die während einer Bereitstellung aufgetreten sind.

Verbrauch:

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

Das ist eine clevere Alternative, die ich mit der API/Powershell-Route statt einer EXE-Anweisung gemacht habe, da es etwas weniger Abhängigkeiten erforderte ... obwohl im Nachhinein die zusätzliche Komplexität des Skripts die EXE in der Umgebung überwiegen würde. Danke für die Eingabe! –

+0

David, Ja API funktioniert auch gut. Wir verwenden es, wenn wir ein Skript vom Backend ausführen, aber wir verwenden hauptsächlich Self-Service-Deploys in niedrigeren Umgebungen, und TFS-Build-Definitionen können die Fehler korrekt erfassen. Das Ausführen von EXE direkt von der Powershell macht keinen guten Job. – Vinnie