SPARK从FTP读取CSV:输入路径不存在

时间:2016-09-14 21:11:27

标签: csv apache-spark ftp pyspark pyspark-sql

我正在尝试做一些本来应该很简单但却无法做到的事情。

我在客户的FTP服务器中有一个.csv文件。路径是这样的:

ftp://[user]:[passwd]@[IP-ADDRESS]/file.csv

通过复制和粘贴地址,我可以轻松地在我的浏览器(或任何其他程序)上访问该文件。但是我不能在pyspark上访问它。

以下是我要做的事情,使用数据库spark-csv(https://github.com/databricks/spark-csv):

file_path = ftp://[user]:[passwd]@[IP-ADDRESS]/file.csv
reader = sqlContext.read.format('com.databricks.spark.csv')
         .options(header=False, charset='cp860', inferschema='true', delim=";")
         .load(file_path)

我收到以下错误:

org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: ftp://[user]:[passwd]@[IP-ADDRESS]/file.csv

尝试将文件作为文本文件读取:

df = sqlContext.read.text("ftp://[user]:[passwd]@[IP-ADDRESS]/SALES_37_TIRADENTES_2016-09-01.csv", )
df.collect()

错误:

Py4JJavaError: An error occurred while calling o147.collectToPython.
: java.io.IOException: No input paths specified in job

我很确定这与FTP访问有关,但我不确定。

修改

我最终使用Python的ftplib下载文件并将文件加载到RDD中。如果数据的大小太大,可能是次优的方法,但它可以工作。

2 个答案:

答案 0 :(得分:2)

您可以使用 SparkFiles 从FTP使用文件 http://spark.apache.org/docs/latest/api/python/pyspark.html

<强> addFile(路径)

在每个节点上添加要使用此Spark作业下载的文件。传递的路径可以是本地文件,HDFS(或其他Hadoop支持的文件系统)中的文件,也可以是HTTP,HTTPS或FTP URI。

要在Spark作业中访问该文件,请使用带有文件名的L {SparkFiles.get(fileName)}来查找其下载位置。

>>> from pyspark import SparkFiles
>>> path = os.path.join(tempdir, "test.txt")
>>> with open(path, "w") as testFile:
...    _ = testFile.write("100")
>>> sc.addFile(path)
>>> def func(iterator):
...    with open(SparkFiles.get("test.txt")) as testFile:
...        fileVal = int(testFile.readline())
...        return [x * fileVal for x in iterator]
>>> sc.parallelize([1, 2, 3, 4]).mapPartitions(func).collect()
[100, 200, 300, 400]

以下测试(pyspark - 1.5.2)正在运行:

from pyspark import SparkFiles

file_path = "ftp://ftp:ftp@ftp.ed.ac.uk/pub/Unix/Win2000_PlainPassword.reg"
sc.addFile(file_path)

filename = SparkFiles.get(file_path.split('/')[-1])

rdd = sc.textFile("file://"+filename)
rdd.take(10)
rdd.collect()

答案 1 :(得分:0)

这里有一些可能有用的东西(scala版本,使用spark 1.6.3测试)

首先使用Spark上下文中的 wholeTextFiles 方法获取文件

val dataSource = "ftp://[user]:[passwd]@[IP-ADDRESS]"

val fileRDD = sc.wholeTextFiles(dataSource).values

然后使用您的选项

实例化CsvParser
val csvParser: CsvParser = new CsvParser().withUseHeader(true).withInferSchema(true).withDelimiter(';').withCharset("cp860")

(如果您不想使用标题,请不要忘记删除第一行)

最后

val df = csvParser.csvRdd(sq, fileRDD)
df.collect()

希望这有帮助!