Behebung allgemeiner Probleme mit Datentypen in Talend
In diesem Artikel wird erläutert, wie Sie bei der Verwendung der Talend-Datentypen gängige Probleme vermeiden können.
Weitere Informationen zum Mapping von Datentypen in Talend Studio finden Sie unter Datentyp-Mapping.
Reguläre Datentypen
Zahlen
Java- und Datenbank-Anbieter stellen unterschiedliche numerische Implementierungen bereit. Der JDBC-Treiber sollte dabei den Übergang ohne jeden Datenverlust sicherstellen.
Allerdings gibt es Typen, bei denen dies nicht unbedingt möglich ist. Gleitkomma- bzw. doppelte Gleitkommazahlen können keine genauen Werte aufnehmen. Mathematische Operationen mit Zahlen dieses Typs ergeben unterschiedliche Resultate je nach Ausführungsreihenfolge der Operationen. Es hat sich bewährt, zunächst die kleineren Zahlen zu summieren und dann die größeren hinzuzufügen.
Ein anderer gängiger Fehler wird bei der Verwendung von globalMap
gemacht. Sie müssen die Klasse („Class“) anstelle der Primitiven verwenden.
int
>Integer
double
>Double
Bei der Konvertierung einer Zeichenfolge (String) in eine Zahl können Sie Folgendes verwenden:
Integer.valueOf
/Integer.parseInt
Double.valueOf
/Double.parseDouble
Datum („Date“)
java.util.Date
und java.sql.Date
enthalten Zeitstempel. Die Komponente tLogRow zeigt diese Zeitstempel gemäß dem von Ihnen konfigurierten Muster an. Aber auch wenn das Muster nur YYYY
(JJJJ) umfasst, enthält das zugrunde liegende Datenobjekt dennoch weitere Informationen. Ein Beispiel für diese Informationen sind Zeitzonen, die häufig übersehen werden, was zu einer unerwarteten Verschiebung von Daten führen kann.
Wenn beispielsweise eine Datenbank ein Datum als 2021-03-10 Midnight
(10.03.2021 Mitternacht) zurückgibt, die andere Datenbank diese Datumsangabe jedoch als 2021-03-10 Midnight in Central Europe GMT+2
(10.03.2021 Mitternacht in Mitteleuropa GMT+2) verarbeitet, wird das Datum zur Speicherung in UTC konvertiert und in einen Datumstyp umgewandelt, woraus sich nach der Ingestion das Datum 2021-03-09
(09.03.2021) ergibt. Das wird in vielen Fällen als Bug interpretiert, wobei es eine logische Erklärung dafür gibt.
Die Datenbank speichert das Objekt als 2021-03-10
(10.03.2021).
Das Objekt wird an Java übergeben und wird dann (je nach verwendeter Konvertierung) zu:
2021-03-10 00:00:00.000 UTC
2021-03-10 02:00:00.000 GMT+2
Anschließend erfolgt die Übergabe an die Datenbank, die das Datum folgendermaßen verarbeitet:
2021-03-10 00:00:00.000 GMT+2
2021-03-09 22:00:00.000 UTC
Durch die Konvertierung in UTC wird das Datum um einen Tag vorverlegt. Wenn Sie demzufolge datumsbezogene Probleme antreffen, sollten Sie stets das gesamte Datum analysieren, d. h. einschließlich Zeitzone, Stunden und Sekunden.
Genauigkeit
Da Talend java.util.Date
verwendet, ist keine Mikro- und Nanosekunden-Genauigkeit verfügbar. Allerdings prüfen einige Komponenten ggf., ob es sich bei dem eingehenden Objekttyp um java.sql.Timestamp
handelt. In diesem Fall sind ebenfalls Nanosekunden verfügbar. Um dies nutzen zu können, müssen Sie den Objekttyp („Object“) in der Schemadefinition auswählen, wobei das von den Quell- und Zielkomponenten unterstützt werden muss.
Experimentelle Ausführung
Zur Behebung von Problemen können Sie Folgendes versuchen:
- Verwenden Sie eine tFileOutput-Komponente, um die Werte zu extrahieren und zu lesen. Auf diese Weise haben Sie die Zeitzone besser im Griff.
- Verwenden Sie den Parameter
-Duser.timezone
, um zu ermitteln, ob sich dadurch das Verhalten ändert. Weitere Informationen finden Sie unter „Zeitzoneneinstellungen in JRE“. - In der Dokumentation des JDBC-Treibers finden Sie Informationen zur Handhabung dieser Zeitzonen.
- Verwenden Sie eine tLogRow-Komponente mit folgendem Muster und Ergebnis:
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-04T12:08:56.235-07:00
Die Zieldatenbank ist dann unter Umständen in der Lage, den mit der Zeitzone verknüpften Zeitstempelteil der vorherigen Beispiele zu speichern. Das könnte eine Datumsverschiebung zur Folge haben.
Mögliche Workarounds
Verwenden Sie Zeichenfolgen (Strings), um zu ermitteln, ob die Datenbank bzw. die zugehörigen Treiber die Transformation verarbeiten können. Bei Zeichenfolgen gilt das WYSIWYG-Prinzip (Echtzeitdarstellung), d. h. es gibt keine zusätzlichen verborgenen Informationen.
Konvertierung zwischen Zeitzonen mit Java-Code in einer tJavaRow-Komponente:
String pattern = "yyyy-MM-dd";
log.info(TalendDate.formatDate(pattern, input_row.startDate));
output_row.startDateUTC = TalendDate.parseDateInUTC("yyyy-MM-dd zzz",
TalendDate.formatDate("yyyy-MM-dd", input_row.startDate)+" UTC");
Weitere Informationen zum Verhalten des Datumstyps finden Sie unter Denkfehler in Verbindung mit Kalenderdaten....
Byte/Binär („byte[] / binary“)
Dieser Datentyp wird in der Regel mit Bildern, BLOB und anderen Binärdaten verwendet.
Einige Komponenten verarbeiten das Binärformat jedoch unter Umständen im Base64-kodierten Format als String-Darstellung (Zeichenfolge). Der geläufigste Fehler in Verbindung mit diesem Typ tritt auf, wenn stattdessen „Objekt“ („Object“) verwendet wird, d. h. in den Logs erscheint ein Eintrag wie @[aaa123
, da bei Verwendung von .toString()
für ein Objekt die Objekt-ID anstelle des Objektwerts zurückgegeben wird.
Objekt („Object“)
Eine andere Bezeichnung für diesen Datentyp könnte Other
(Andere) lauten. Dieser Typ kann nämlich jeden der oben beschriebenen Datentypen in Java repräsentieren. Das kann sich als hilfreich erweisen, um einige Sondertypen, wie z. B. einen Zeitstempel („timestamp“), darzustellen.
Um auf alle verfügbaren Informationen zugreifen zu können, müssen Sie ihn jedoch wieder in seinen ursprünglichen Typ umwandeln.
Vergleich
==
. Andere Datentypen jedoch, wie z. B. Zeichenfolgen („String“), müssen unter Verwendung der Funktion .equals()
(Gleich) oder .compareTo()
(Vergleichen mit) verglichen werden.
Geläufige Fehler:
context.value == "foo"
funktioniert nicht.
context.value.equals("foo")
kann eine NullPointerException zur Folge haben. "foo".equals(context.value)
hingegen ergibt „false“ bei einem Wert gleich null.
Spezielle Datentypen
Snowflake - Geografischer Typ („Geography“)
Snowflake unterstützt den Typ „Geography“. Allerdings wird dieser Typ von Talend standardmäßig nicht unterstützt.
Weitere Informationen zur Konvertierung von Zeichenfolgen („Strings“) in den geografischen Typ („Geography“) finden Sie in der Snowflake-Dokumentation für Raumbezogene Datentypen.
Durch die automatische Anwendung der Funktion TO_GEOGRAPHY können Sie ein Schema erstellen und die Daten mithilfe einer tFixedFlowInput-Komponente testen.
Definieren Sie Ihr Eingabeschema wie oben gezeigt und stellen Sie die geografischen Daten durch die folgende Zeichenfolge dar:
POINT(-122.35 37.55)
Die Snowflake-Tabelle wird folgendermaßen definiert:
create table "SAMPLEGEO" (str1 text, str2 geography, int1 number);
Die Verwendung der Komponente tSnowflakeOutputBulkExec ergibt Folgendes:
Beachten Sie, dass die Talend-Zeichenfolge in Snowflake in geografische Daten umgewandelt wird.
Bei Verwendung des Datentyps „String“ oder „Object“ sollte stets geprüft werden, ob spezielle bzw. exotische Datentypen in die Datenbank geladen werden können.