Allgemeine Operationen in Java-UDFs

Unter diesem Thema wird gezeigt, wie Java-UDFs gängige Operationen durchführen können, wie das Lesen aus einer Datei (z. B. einer Konfigurationsdatei).

Unter diesem Thema:

Lesen einer Datei aus einer Java-UDF heraus

Beispielcode zum Lesen einer Datei

Eine Java-UDF kann Dateien (z. B. Konfigurationsdateien) lesen, die in einem Stagingbereich gespeichert wurden. Der Dateiname und der Name des Stagingbereichs müssen in der IMPORTS-Klausel des Befehls CREATE FUNCTION angegeben worden sein.

Wenn eine Datei in der IMPORTS-Klausel einer UDF angegeben wird, kopiert Snowflake diese Datei vom Stagingbereich in das Home-Verzeichnis der UDF (auch Importverzeichnis genannt), welches das Verzeichnis ist, aus dem die UDF die Datei schließlich ausliest.

Da importierte Dateien in ein einziges Verzeichnis kopiert werden und innerhalb dieses Verzeichnisses eindeutige Namen haben müssen, muss jede Datei in der IMPORTS-Klausel einen eindeutigen Namen haben, auch wenn sich die Dateien in verschiedenen Stagingbereichen oder verschiedenen Unterverzeichnissen innerhalb eines Stagingbereichs befinden.

Im folgenden Beispiel wird eine Java-UDF zum Lesen einer Datei erstellt und aufgerufen.

Der Java-Quellcode erstellt eine Java-Methode mit dem Namen read_file(). Die UDF verwendet diese Methode.

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

class TestReadRelativeFile {
    public static String read_file(String fileName) throws IOException {
        StringBuilder contentBuilder = new StringBuilder();
        String importDirectory = System.getProperty("com.snowflake.import_directory");
        String fPath = importDirectory + fileName;
        Stream<String> stream = Files.lines(Paths.get(fPath), StandardCharsets.UTF_8);
        stream.forEach(s -> contentBuilder.append(s).append("\n"));
        return contentBuilder.toString();
    }
}

Mit dem folgenden SQL-Code wird die UDF erstellt. Dieser Code geht davon aus, dass der Java-Quellcode kompiliert und in einer JAR-Datei mit dem Namen TestReadRelativeFile.jar bereitgestellt wurde, die von der UDF importiert wird. Die zweite und die dritte importierte Datei, my_config_file_1.txt und my_config_file_2.txt, sind Konfigurationsdateien, die von der UDF gelesen werden können.

CREATE FUNCTION file_reader(file_name VARCHAR)
RETURNS VARCHAR
LANGUAGE JAVA
IMPORTS = ('@my_stage/my_package/TestReadRelativeFile.jar',
           '@my_stage/my_path/my_config_file_1.txt',
           '@my_stage/my_path/my_config_file_2.txt')
HANDLER = 'my_package.TestReadRelativeFile.read_file';

Der folgende Code ruft die UDF auf:

SELECT file_reader('my_config_file_1.txt') ...;
...
SELECT file_reader('my_config_file_2.txt') ...;

Entscheiden, ob Zugriff auf Datei im komprimierten oder nicht komprimierten Format erfolgen soll

Dateien können in einem Stagingbereich in komprimiertem oder unkomprimiertem Format gespeichert werden. Der Benutzer kann die Datei komprimieren, bevor er sie in den Stagingbereich kopiert, oder er kann im Befehl PUT anweisen, die Datei zu komprimieren.

Wenn Snowflake eine im GZIP-Format komprimierte Datei von einem Stagingbereich in das Home-Verzeichnis der UDF kopiert, kann Snowflake die Datei so kopieren, wie sie ist, oder Snowflake kann den Inhalt vor dem Schreiben der Datei dekomprimieren.

Wenn die Datei im Stagingbereich komprimiert ist und wenn Sie möchten, dass die Kopie im Home-Verzeichnis der UDF ebenfalls komprimiert vorliegt soll, dann verwenden Sie bei der Angabe des Dateinamens in der IMPORTS-Klausel einfach den ursprünglichen Dateinamen (z. B. „MyData.txt.gz“). Beispiel:

... imports = ('@MyStage/MyData.txt.gz', ...)

Wenn die Datei im Stagingbereich GZIP-komprimiert ist, Sie aber möchten, dass die Kopie im UDF-Home-Verzeichnis nicht komprimiert ist, dann lassen Sie bei der Angabe des Dateinamens in der IMPORTS-Klausel die Erweiterung „.gz“ weg. Wenn der Stagingbereich beispielsweise „MyData.txt.gz“ enthält, Sie aber möchten, dass Ihre UDF die Datei im nicht komprimierten Format liest, dann geben Sie in der IMPORTS-Klausel „MyData.txt“ an. Wenn es noch keine nicht komprimierte Datei mit dem Namen „MyData.txt“ vorhanden ist, dann sucht Snowflake nach „MyData.txt.gz“ und schreibt automatisch eine dekomprimierte Kopie „MyData.txt“ in das Home-Verzeichnis der UDF. Ihre UDF kann dann die nicht komprimierte Datei „MyData.txt“ öffnen und lesen.

Beachten Sie, dass die intelligente Dekomprimierung nur für die Kopie im UDF-Home-Verzeichnis gilt. Die Originaldatei im Stagingbereich wird nicht verändert.

Folgen Sie den bewährten Verfahren für den Umgang mit komprimierten Dateien:

  • Befolgen Sie die korrekten Konventionen für die Dateibenennung. Wenn eine Datei im GZIP-komprimierten Format vorliegt, fügen Sie am Ende des Dateinamens die Erweiterung „.gz“ hinzu. Wenn eine Datei nicht im GZIP-komprimierten Format vorliegt, darf der Dateiname nicht mit der Erweiterung „.gz“ enden.

  • Vermeiden Sie es, Dateien zu erstellen, deren Namen sich nur durch die Endung „.gz“ unterscheiden. Erstellen Sie z. B. nicht gleichzeitig „MyData.txt“ und „MyData.txt.gz“ im selben Stagingbereich und Verzeichnis, und versuchen Sie nicht, sowohl „MyData.txt“ als auch „MyData.txt.gz“ im selben CREATE FUNCTION-Befehl zu importieren.

  • Komprimieren Sie Dateien nicht doppelt. Wenn Sie z. B. eine Datei manuell komprimieren und dann diese Datei ohne Verwendung von AUTO_COMPRESS=FALSE mit PUT komprimieren, wird die Datei ein zweites Mal komprimiert. Bei der intelligenten Dekomprimierung wird sie nur einmal dekomprimiert, sodass die Datendatei (oder JAR-Datei) immer noch komprimiert ist, wenn sie im Home-Verzeichnis der UDF gespeichert ist.

  • In Zukunft erweitert Snowflake möglicherweise die intelligente Dekomprimierung auf weitere Komprimierungsalgorithmen als nur GZIP. Um Kompatibilitätsprobleme in Zukunft zu vermeiden, wenden Sie folgende bewährte Verfahren auf Dateien an, die einen beliebigen Typ von Komprimierung verwenden.

Bemerkung

Auch JAR-Dateien können in einem Stagingbereich in komprimiertem oder unkomprimiertem Format gespeichert werden. Snowflake dekomprimiert automatisch alle komprimierten JAR-Dateien, bevor sie der Java-UDF zur Verfügung gestellt werden.