web-dev-qa-db-fra.com

Spark: Lecture du fichier uniquement si le chemin existe

J'essaie de lire les fichiers présents à la Sequence de Chemins en scala. Voici l'exemple de code (pseudo):

val paths = Seq[String] //Seq of paths
val dataframe = spark.read.parquet(paths: _*)

Maintenant, dans la séquence ci-dessus, certains chemins existent alors que d'autres ne le sont pas. Existe-t-il un moyen d'ignorer les chemins manquants lors de la lecture des fichiers parquet (pour éviter org.Apache.spark.sql.AnalysisException: Path does not exist)?

J'ai essayé le ci-dessous et cela semble fonctionner, mais je finis par lire deux fois le même chemin, ce que j'aimerais éviter de faire:

val filteredPaths = paths.filter(p => Try(spark.read.parquet(p)).isSuccess)

J'ai vérifié la méthode options pour DataFrameReader mais cela ne semble pas avoir une option semblable à ignore_if_missing.

De plus, ces chemins peuvent être hdfs ou s3 (cette Seq est passée en tant qu'argument de méthode) et, lors de la lecture, je ne sais pas si un chemin est s3 ou hdfs, donc nous ne pouvons pas utiliser l'API spécifique s3 ou hdfs pour vérifier son existence.

8
Darshan Mehta

Vous pouvez filtrer les fichiers non pertinents comme dans la réponse de @ Psidom. Dans spark, le meilleur moyen consiste à utiliser la configuration hadoop interne à spark. Étant donné que la variable d'allumage est appelée "spark", vous pouvez faire:

import org.Apache.hadoop.fs.FileSystem
import org.Apache.hadoop.fs.Path

val hadoopfs: FileSystem = FileSystem.get(spark.sparkContext.hadoopConfiguration)

def testDirExist(path: String): Boolean = {
  val p = new Path(path)
  hadoopfs.exists(p) && hadoopfs.getFileStatus(p).isDirectory
}
val filteredPaths = paths.filter(p => testDirExists(p))
val dataframe = spark.read.parquet(filteredPaths: _*)
8
Assaf Mendelson

Pourquoi ne pas filtrer la paths firstly`:

paths.filter(f => new Java.io.File(f).exists)

Par exemple:

Seq("/tmp", "xx").filter(f => new Java.io.File(f).exists)
// res18: List[String] = List(/tmp)
1
Psidom