Daten mit Microsoft Dallas anreichern

July 11, 2010 16:58 by Till

Seit einigen Monaten bietet Microsoft im Rahmen seiner Cloud Computing Strategie das Projekt Microsoft “Dallas” als CTP an; seit Mai 2010 ist das Projekt auch Bestandteil von Microsoft PinPoint.

Microsoft “Dallas” ist ein Service, über den auf freie und kommerzielle Daten unterschiedlichster Anbieter über eine einheitliche REST-basierende API zugegriffen werden kann. Der Zugriff auf die Daten kann dabei per Transaktion oder als Abonnement nach dem Motto “pay-as-you-grow” abgerechnet werden. Aktuell werden Daten von Namenhaften Anbietern wie der Nasa, National Geographic, Navteq, PitneyBowes oder undata - größtenteils noch kostenlos – angeboten.

Weitere Informationen zu Microsoft Dallas gibt es in einem Webcast auf Channel 9 sowie im Windows Azure Platform Training Kit.

REST-basierende API eignen sich recht gut, um sie direkt innerhalb der Integration Services anzusprechen. Auch mein Codeplex Projekt SSIS SMSTask nutzt z.B. für das versenden von SMS entsprechende API. Ein großer Vorteil des Projektes Microsoft “Dallas” ist die Bereitstellung einer Proxy Klasse zu jedem Datenanbieter. Hierdurch kann die Integration mit wenigen Zeilen Code begonnen werden.

ShowDataSetLogo Im folgenden Beispiel zeige ich, wie man Daten aus der AdventureWorks Datenbank um zusätzlichen Informationen des Anbieters “Weather Central Global Forecast and Data Services ” anreichern kann.

 

 

Für die Demo benötigt man einen Zugang zu Microsoft “Dallas”, den man sich bei einer vorhandenen Windows Live ID sehr schnell kostenlos anlegen kann. Als Grundlage für die Daten verwende ich die AdventureWorks2008 Datenbank, in der bereits Geodaten vorhanden sind.

Da für die Anfrage an den Service keine Geography-Instanz verwendet werden kann, sondern die Daten einzeln als Längen- und Breitengrade übergeben werden müssen, werden diese Eigenschaften in der Quelle mit abgefragt (Zeile 7/8).

   1: SELECT TOP 1000 [AddressID]
   2:       ,[AddressLine1]
   3:       ,[AddressLine2]
   4:       ,[City]
   5:       ,[StateProvinceID]
   6:       ,[PostalCode]
   7:       ,SpatialLocation.Long AS Long
   8:       ,SpatialLocation.Lat AS Lat
   9:       ,[rowguid]
  10:       ,[ModifiedDate]
  11:   FROM [AdventureWorks2008].[Person].[Address]

Die Daten laufen aus der Quelle direkt in die Script Component. Aus dem Datenfluss werden die Spalten Latitude und Longitude als Eingangsspalten definiert, zusätzlich werden die 4 neuen Ausgabespalten  Time, Temperature, FeelsLike und RelativeHumidity angelegt.

Da die oben bereits angesprochene Proxy Klasse Referenzen zu System.Data.Linq sowie System.XML.Linq verwendet, muss innerhalb der Script Component Projektmappe im Visual Studio als erstes das .Net Framework von 2.0 auf 3.5 umgestellt werden. Danach werden die beiden entsprechenden Referenzen gesetzt und die zuvor heruntergeladene Proxy Klasse der Projektmappe hinzugefügt.

image image

Im Script unten füge ich nur jeweils die erste Zeile aus dem zurückgelieferten Dataset den Daten im Datenfluss an. In Zeile 11 und 12 Kürze ich zusätzlich die Geodaten aus der AdventureWorks Datenbank auf 5 Zeichen, da der Wetter-Dienst bei den genauen Daten leider zu häufig keine Treffer zurückgibt. 

   1: public override void Input0_ProcessInputRow(Input0Buffer Row)
   2:     {
   3:         string accountKey = "--- YOUR ACCOUNTKEY ---";
   4:         System.Guid uniqueUserID = new Guid("--- YOUR UNIQUE USERID ---");
   5:         DailyForecastService Weather = new DailyForecastService(accountKey, uniqueUserID);
   6:         if (!Row.Long_IsNull && !Row.Lat_IsNull)
   7:         {
   8:             try
   9:             {
  10:                 List<DailyForecastItem> dfc = Weather.Invoke(Row.Lat.ToString().Substring(0, 5)
  11:                     , Row.Long.ToString().Substring(0, 5), null, "metric");
  12:                 Row.RelativeHumidity = dfc[0].RelativeHumidityMax;
  13:                 Row.Temperature = dfc[0].RelativeHumidityMax;
  14:                 Row.Time = dfc[0].Start;
  15:                 Row.FeelsLike = dfc[0].FeelsLikeMax;
  16:             }
  17:             catch (Exception ex)
  18:             {
  19:                 ComponentMetaData.FireWarning(0, "Weather Central", "Invalid coordinates: ("
  20:                     + Row.Lat.ToString() + " " + Row.Long.ToString() + ")", null, 0);
  21:             }
  22:         }
  23:     }

Liefern Anfragen an den Service einen Fehler zurück, so führe ich das hier auf die Geokoordinaten zurück und gebe eine entsprechende Warnung mit der betreffenden Geokoordinate aus (Zeile 20).

image 
Um nun sämtliche zurückgelieferten Daten zu verwenden, also auch wirkliche Vorraussagen meinem Datenfluss hinzuzufügen, füge ich der Script Component noch einen weiteren OutputBuffer “WeatherOutput” hinzu. Dieser bekommt zusätzlich zu den oben genannten 4 Spalten noch die AdressID der Originaldaten, um so später wieder eine vernünftige Zuordnung herstellen zu können. Im Standard OutputBuffer lösche ich wieder die zuvor hinzugefügten Spalten.

 

image

 image

   1: public override void Input0_ProcessInputRow(Input0Buffer Row)
   2:     {
   3:         string accountKey = "--- YOUR ACCOUNTKEY ---";
   4:         System.Guid uniqueUserID = new Guid("--- YOUR UNIQUE USERID ---");
   5:         DailyForecastService Weather = new DailyForecastService(accountKey, uniqueUserID);
   6:         if (!Row.Long_IsNull && !Row.Lat_IsNull)
   7:         {
   8:             try
   9:             {
  10:                 List<DailyForecastItem> dfc = Weather.Invoke(Row.Lat.ToString().Substring(0, 5)
  11:                     , Row.Long.ToString().Substring(0, 5), null, "metric");
  12:                 foreach (DailyForecastItem item in dfc)
  13:                 {
  14:                     WeatherOutputBuffer.AddRow();
  15:                     WeatherOutputBuffer.AddresID = Row.AddressID;
  16:                     WeatherOutputBuffer.RelativeHumidity = item.RelativeHumidityMax;
  17:                     WeatherOutputBuffer.Temperature = item.RelativeHumidityMax;
  18:                     WeatherOutputBuffer.Time = item.Start;
  19:                     WeatherOutputBuffer.FeelsLike = item.FeelsLikeMax;
  20:                 }
  21:  
  22:             }
  23:             catch (Exception ex)
  24:             {
  25:                 ComponentMetaData.FireWarning(0, "Weather Central", "Invalid coordinates: (" 
  26:                     + Row.Lat.ToString() + " " + Row.Long.ToString() + ")", null, 0);
  27:             }
  28:         }
  29:     }

image

Zugegebener Maßen liegen die Ansatzpunkte, Daten mit Wetterdaten anzureichern, nicht wirklich auf der Hand. Aber das Beispiel zeigt sehr gut, wie einfach es ist, Daten mit Microsoft “Dallas” und den gegebenen Proxy Klassen um zusätzliche Informationen anzureichern.


Replacing Data Conversion Component for SSIS

July 8, 2010 02:48 by till

clip_image001Todd McDermid hat bei Codplex eine neue SSIS Komponente veröffentlicht. Die Replacing Data Conversion Component for SSIS ist eine Erweiterung des bestehenden Datenkonvertierungstask.

Die Komponente erstellt, im Gegensatz zur Standard Komponente, nicht einfach eine neue Spalte, in die die konvertierten Daten kopiert werden, sondern ersetzt die bestehende Spalte. In vielen Projekten, definitiv eine Komponente die ich mir schon länger gewünscht habe.

Die Komponente besitzt einen Simple Mode und einen Complex Mode. Im Simple Mode können mit wenigen Klicks Spalten eines bestimmten Datentyps in einen anderen Datentyp konvertiert werden.

ReplacingDataConversion%20Editor-Simple[1]

Der Complex Mode bietet die Möglichkeit ganz gezielt einzelne Spalten von einem Datentyp in einen anderen Datentyp zu konvertieren, ohne dabei die Spaltenbezeichnung zu ändern.

Aus meiner Sicht bringt die Komponente allerdings auch zwei Nachteile mit sich, die man in größeren Projekten beachten sollte. 

Um die bestehende(n) Spalte(n) zu löschen und mit einem anderen Datentypen neu zu erstellen, müssen die Daten in einen neuen Output-Buffer kopiert werden. Die Verarbeitung in der Komponente findet dabei asynchron statt. Dadurch ist die Replacing Data Conversion Component eine sogenannte Blocking-Component, da sämtliche Daten von der Komponente erst vollständig geladen werden müssen, bevor sie weiter verarbeitet werden können; ähnlich wie man es z.B. vom Sortieren-Task kennt. Asynchrone Komponente verbrauchen mehr Speicher und beeinflussen wesentlich die Performance des Paketes. Todd gibt in punkto Performance auch noch die Entwicklung in .NET anstatt C/C++, wie beim originalen Datenkonvertierungstask, als weiteren Nachteil an.

Der zweite Nachteil aus meiner Sicht ist die nicht mehr direkt gegebene Nachvollziehbarkeit der Daten. Normalerweise empfehle ich Änderungen an Daten (z.B. bei Konvertierungen) durch eine Namenskonvention innerhalb des Datenflusses zu dokumentieren. Bei unseren Komponenten vergeben wir standardmäßig Präfixe bei neu erstellten Spalten. So wird z.B. aus der Spalte “Street” die mit datenfabrik.address bereinigt wurde, automatisch die Spalte “dfad_Street”. Eine Spalte die nach mehreren Transformationen immer noch den identischen Namen wie die ursprüngliche Quellspalte besitzt, führt  nach meinen Erfahrungen in größeren Paketen irgendwann zu Fehlern.

Nur zur Info, die Komponente wird von Todd McDermind über den Source Code Bereich zur Verfügung gestellt.


PASS Regionalgruppe Köln/Bonn/Düsseldorf

July 2, 2010 15:16 by till

image Am 11.07.2010 findet das letzte Spiel der WM 2010 statt. Aber Was kommt danach? Wie verbringt man die Zeit nach der WM? Am besten fängt man damit an und pflegt wieder seine SQL Server Kontakte und zwar direkt am 12.07.2010 in Köln bei Microsoft. Wir treffen uns mit Regionalgruppe Köln/Bonn/Düsseldorf noch einmal vor der langen Sommerpause (im August findet kein Treffen statt…).

Für dieses Treffen konnten wir mit Hilmar Buchta wieder einen Sprecher der ORAYLIS GmbH gewinnen und können mit Ami Levin von DBSophic auch mal einen sehr bekannten internationalen Sprecher in der Regionalgruppe Köln/Bonn/Düsseldorf begrüßen.

 

Das Leben nach dem Zauberer – Was tun, wenn der Wizard seine Arbeit abgeschlossen hat?, Hilmar Buchta

Dank des Cube-Wizards ist es in den Microsoft BI-Werkzeugen sehr leicht möglich, einen Cube und die dazugehörenden Dimension auf Basis einer Datenquelle zu erstellen. Allerdings ist der Cube dann noch nicht wirklich bereit für die Anwendung. Der Vortrag stellt die wichtigsten Themen dar, an die man auf alle Fälle denken sollten und gibt auch ein paar Tipps und Tricks, wie man den Cube rund und gut anwendbar machen kann.

Hilmar Buchta ist Berater und Architekt für Microsoft BI-Lösungen bei der ORAYLIS GmbH, Blogger (ms-olap.blogspot.com) und selbstverständlich PASS Mitglied.

 

Physical Join Operators in SQL Server, Ami Levin

SQL Server implements three different physical operators to perform joins. In this session, we will examine how each of these operators works, including its advantages and challenges. Using real life examples, we will better understand the logic behind the optimizer’s decisions on which operator to use for various joins. Finally, we will review how to avoid common join-related pitfalls to achieve performing queries

Ami Levin is a Microsoft SQL Server MVP, with over 20 years experience in the IT industry. For the past 12 years, he has been consulting, speaking and teaching SQL worldwide. He manages the Israeli SQL Server user group (http://www.sqlserver.co.il/), leads the SQL Server support forum in Hebrew, and is a regular speaker at Microsoft conferences. Ami is the CTO and co-founder of DBSophic, a software company that develops innovative solutions for performance optimization of SQL Server application workloads.

 

Weitere Informationen findet ihr auf der Seite unserer Regionalgruppe.