2017-10-20 32 views
1

J'ai un script U-SQL où j'ai besoin de traiter certaines données. Les données sont stockées dans blob, avec ~ 100 fichiers par jour dans cette structure de dossiers: /{year}/{month}/{day}/{hour}/filenames.tsvComment puis-je définir plusieurs modèles de fichier d'entrée dans USQL?

Obtenir un jour de données est facile, il suffit de mettre un caractère générique à la fin et il va sélectionner tous les fichiers pour toutes les heures pour la journée.

Cependant, dans mon script je veux lire le jour actuel et les 2 dernières heures du jour précédent. La façon naïve est avec 3 déclarations d'extrait de cette façon:

DECLARE @input1 = @"/data/2017/10/08/22/{*}.tsv"; 
DECLARE @input2 = @"/data/2017/10/08/23/{*}.tsv"; 
DECLARE @input3 = @"/data/2017/10/09/{*}.tsv"; 

@x1 = EXTRACT .... FROM @input1 USING Extractors.Tsv(); 
@x2 = EXTRACT .... FROM @input2 USING Extractors.Tsv(); 
@x3 = EXTRACT .... FROM @input3 USING Extractors.Tsv(); 

Mais dans mon cas, chaque ligne d'extrait est très long et compliqué (~ 50 colonnes) en utilisant le AvroExtractor, donc je préférerais vraiment seulement spécifier les colonnes et extracteur une fois au lieu de 3 fois. En outre, en ayant 3 entrées il n'est pas possible du côté de l'appelant de décider combien d'heures les jours précédents doivent être lus.

Ma question est comment puis-je définir cela de manière pratique, idéalement en utilisant une seule instruction d'extrait?

Répondre

2

Vous pouvez inclure votre logique dans une procédure stockée U-SQL afin qu'elle soit encapsulée. Ensuite, vous n'avez qu'à faire quelques appels à la proc. Un exemple simple:

CREATE PROCEDURE IF NOT EXISTS main.getContent(@inputPath string, @outputPath string) 
AS 
BEGIN; 

    @output = 
     EXTRACT 
     ... 
     FROM @inputPath 
     USING Extractors.Tsv(); 


    OUTPUT @output 
    TO @outputPath 
    USING Outputters.Tsv(); 

END; 

Puis l'appeler (non testé):

main.getContent (
    @"/data/2017/10/08/22/{*}.tsv", 
    @"/output/output1.tsv" 
    ) 

main.getContent (
    @"/data/2017/10/08/23/{*}.tsv", 
    @"/output/output2.tsv" 
    ) 

main.getContent (
    @"/data/2017/10/09/{*}.tsv", 
    @"/output/output3.tsv" 
    ) 

Cela pourrait être une façon d'aller à ce sujet?

+1

Dans mon cas, je voulais traiter les données ensemble, donc à la place d'une procédure, j'ai créé une fonction de valeur table. Mais le principe est exactement comme votre réponse. – viblo