檔案系統介面#

PyArrow 隨附抽象檔案系統介面,以及各種儲存類型的具體實作。

檔案系統介面提供輸入和輸出串流以及目錄操作。公開了底層資料儲存的簡化視圖。資料路徑表示為抽象路徑,即使在 Windows 上也是以 / 分隔,並且不應包含特殊路徑組件,例如 ...。符號連結(如果底層儲存支援)會自動取消引用。僅提供關於檔案條目的基本metadata(例如檔案大小和修改時間)。

核心介面由基底類別 FileSystem 表示。

Pyarrow 原生實作了以下檔案系統子類別

也可以將您自己的 fsspec 相容檔案系統與 pyarrow 功能一起使用,如 搭配 Arrow 使用 fsspec 相容檔案系統 章節所述。

用法#

實例化檔案系統#

FileSystem 物件可以使用建構函式之一建立(並檢查各自建構函式的選項)

>>> from pyarrow import fs
>>> local = fs.LocalFileSystem()

或從 URI 推斷

>>> s3, path = fs.FileSystem.from_uri("s3://my-bucket")
>>> s3
<pyarrow._s3fs.S3FileSystem at 0x7f6760cbf4f0>
>>> path
'my-bucket'

讀取和寫入檔案#

PyArrow 中多個與 IO 相關的函數接受 URI(並推斷檔案系統)或明確的 filesystem 引數,以指定要從哪個檔案系統讀取或寫入。例如,pyarrow.parquet.read_table() 函數可以用以下方式使用

import pyarrow.parquet as pq

# using a URI -> filesystem is inferred
pq.read_table("s3://my-bucket/data.parquet")
# using a path and filesystem
s3 = fs.S3FileSystem(..)
pq.read_table("my-bucket/data.parquet", filesystem=s3)

檔案系統介面進一步允許直接開啟檔案進行讀取(輸入)或寫入(輸出),這可以與處理檔案類物件的函數結合使用。例如

import pyarrow as pa

local = fs.LocalFileSystem()

with local.open_output_stream("test.arrow") as file:
   with pa.RecordBatchFileWriter(file, table.schema) as writer:
      writer.write_table(table)

列出檔案#

可以使用 FileSystem.get_file_info() 方法檢查檔案系統上的目錄和檔案。若要列出目錄的內容,請使用 FileSelector 物件指定選取

>>> local.get_file_info(fs.FileSelector("dataset/", recursive=True))
[<FileInfo for 'dataset/part=B': type=FileType.Directory>,
 <FileInfo for 'dataset/part=B/data0.parquet': type=FileType.File, size=1564>,
 <FileInfo for 'dataset/part=A': type=FileType.Directory>,
 <FileInfo for 'dataset/part=A/data0.parquet': type=FileType.File, size=1564>]

這會傳回 FileInfo 物件的列表,其中包含關於類型(檔案或目錄)、大小、上次修改日期等的資訊。

您也可以取得單個明確路徑(或路徑列表)的此資訊

>>> local.get_file_info('test.arrow')
<FileInfo for 'test.arrow': type=FileType.File, size=3250>

>>> local.get_file_info('non_existent')
<FileInfo for 'non_existent': type=FileType.NotFound>

本機 FS#

LocalFileSystem 允許您存取本機上的檔案。

如何寫入磁碟並讀回的範例

>>> from pyarrow import fs
>>> local = fs.LocalFileSystem()
>>> with local.open_output_stream('/tmp/pyarrowtest.dat') as stream:
        stream.write(b'data')
4
>>> with local.open_input_stream('/tmp/pyarrowtest.dat') as stream:
        print(stream.readall())
b'data'

S3#

PyArrow 原生實作了與 S3 相容儲存空間的 S3 檔案系統。

S3FileSystem 建構函式具有多個選項來配置 S3 連線(例如憑證、區域、端點覆寫等)。此外,建構函式還將檢查 AWS 支援的已配置 S3 憑證(例如 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 環境變數、AWS 組態檔以及 EC2 節點的 EC2 執行個體中繼資料服務)。

如何從 S3 儲存貯體讀取內容的範例

>>> from pyarrow import fs
>>> s3 = fs.S3FileSystem(region='eu-west-3')

# List all contents in a bucket, recursively
>>> s3.get_file_info(fs.FileSelector('my-test-bucket', recursive=True))
[<FileInfo for 'my-test-bucket/File1': type=FileType.File, size=10>,
 <FileInfo for 'my-test-bucket/File5': type=FileType.File, size=10>,
 <FileInfo for 'my-test-bucket/Dir1': type=FileType.Directory>,
 <FileInfo for 'my-test-bucket/Dir2': type=FileType.Directory>,
 <FileInfo for 'my-test-bucket/EmptyDir': type=FileType.Directory>,
 <FileInfo for 'my-test-bucket/Dir1/File2': type=FileType.File, size=11>,
 <FileInfo for 'my-test-bucket/Dir1/Subdir': type=FileType.Directory>,
 <FileInfo for 'my-test-bucket/Dir2/Subdir': type=FileType.Directory>,
 <FileInfo for 'my-test-bucket/Dir2/Subdir/File3': type=FileType.File, size=10>]

# Open a file for reading and download its contents
>>> f = s3.open_input_stream('my-test-bucket/Dir1/File2')
>>> f.readall()
b'some data'

請注意,為正在使用的儲存貯體配置正確的區域來配置 S3FileSystem 非常重要。如果未設定 region,AWS SDK 將選擇一個值,如果 SDK 版本 <1.8,則預設為 'us-east-1'。否則,它將嘗試使用各種啟發式方法(環境變數、組態設定檔、EC2 中繼資料伺服器)來解析區域。

也可以使用 pyarrow.fs.resolve_s3_region()pyarrow.fs.S3FileSystem.from_uri()S3FileSystem 的儲存貯體名稱解析區域。

以下是一些程式碼範例

>>> from pyarrow import fs
>>> s3 = fs.S3FileSystem(region=fs.resolve_s3_region('my-test-bucket'))

# Or via URI:
>>> s3, path = fs.S3FileSystem.from_uri('s3://[access_key:secret_key@]bucket/path]')

另請參閱

請參閱 AWS 文件,了解配置 AWS 憑證的不同方式。

pyarrow.fs.resolve_s3_region() 用於從儲存貯體名稱解析區域。

疑難排解#

使用 S3FileSystem 時,僅針對嚴重錯誤或列印傳回值產生輸出。為了進行疑難排解,可以使用環境變數 ARROW_S3_LOG_LEVEL 設定日誌層級。必須在執行任何與 S3 互動的程式碼之前設定日誌層級。可能的值包括 FATAL(預設值)、ERRORWARNINFODEBUG(建議)、TRACEOFF

Google 雲端儲存空間檔案系統#

PyArrow 原生實作了 Google 雲端儲存空間 (GCS) 後端檔案系統,用於 GCS 儲存空間。

如果未在 Google Cloud Platform (GCP) 上執行,這通常需要環境變數 GOOGLE_APPLICATION_CREDENTIALS 指向包含憑證的 JSON 檔案。或者,使用 gcloud CLI 在預設位置產生憑證檔案

gcloud auth application-default login

若要連線到公用儲存貯體而不使用任何憑證,您必須將 anonymous=True 傳遞給 GcsFileSystem。否則,檔案系統將報告 Couldn't resolve host name,因為經過驗證和公用存取的主機名稱不同。

範例顯示如何從 GCS 儲存貯體讀取內容

>>> from datetime import timedelta
>>> from pyarrow import fs
>>> gcs = fs.GcsFileSystem(anonymous=True, retry_time_limit=timedelta(seconds=15))

# List all contents in a bucket, recursively
>>> uri = "gcp-public-data-landsat/LC08/01/001/003/"
>>> file_list = gcs.get_file_info(fs.FileSelector(uri, recursive=True))

# Open a file for reading and download its contents
>>> f = gcs.open_input_stream(file_list[0].path)
>>> f.read(64)
b'GROUP = FILE_HEADER\n  LANDSAT_SCENE_ID = "LC80010032013082LGN03"\n  S'

另請參閱

GcsFileSystem 建構函式預設使用 GCS 文件中描述的程序來解析憑證。

Hadoop 分散式檔案系統 (HDFS)#

PyArrow 帶有 Hadoop 檔案系統的綁定 (基於使用 libhdfs 的 C++ 綁定,一個基於 JNI 的介面,連接到 Java Hadoop client)。您可以使用 HadoopFileSystem 建構函式來連接

from pyarrow import fs
hdfs = fs.HadoopFileSystem(host, port, user=user, kerb_ticket=ticket_cache_path)

libhdfs 函式庫是在執行階段載入的 (而不是在連結 / 函式庫載入時期,因為該函式庫可能不在您的 LD_LIBRARY_PATH 中),並且依賴於一些環境變數。

  • HADOOP_HOME:您安裝的 Hadoop 發行版的根目錄。通常包含 lib/native/libhdfs.so

  • JAVA_HOME:您的 Java SDK 安裝位置。

  • ARROW_LIBHDFS_DIR (選填):libhdfs.so 的明確位置,如果它安裝在 $HADOOP_HOME/lib/native 以外的其他地方。

  • CLASSPATH:必須包含 Hadoop jar 檔。您可以使用以下方式設定這些:

    export CLASSPATH=`$HADOOP_HOME/bin/hadoop classpath --glob`
    # or on Windows
    %HADOOP_HOME%/bin/hadoop classpath --glob > %CLASSPATH%
    

    與使用 pa.hdfs.connect 的舊有 HDFS 檔案系統不同,設定 CLASSPATH 不是選填的 (pyarrow 不會嘗試推斷它)。

將與 fsspec 相容的檔案系統與 Arrow 搭配使用#

上述提及的檔案系統由 Arrow C++ / PyArrow 原生支援。然而,Python 生態系統也有幾個檔案系統套件。那些遵循 fsspec 介面的套件也可以在 PyArrow 中使用。

接受檔案系統物件的函式也將接受 fsspec 子類別。例如

# creating an fsspec-based filesystem object for Google Cloud Storage
import gcsfs
fs = gcsfs.GCSFileSystem(project='my-google-project')

# using this to read a partitioned dataset
import pyarrow.dataset as ds
ds.dataset("data/", filesystem=fs)

Azure Blob Storage 也類似

import adlfs
# ... load your credentials and configure the filesystem
fs = adlfs.AzureBlobFileSystem(account_name=account_name, account_key=account_key)

import pyarrow.dataset as ds
ds.dataset("mycontainer/data/", filesystem=fs)

在底層,fsspec 檔案系統物件被包裝成一個基於 python 的 PyArrow 檔案系統 (PyFileSystem),使用 FSSpecHandler。您也可以手動執行此操作以取得具有 PyArrow FileSystem 介面的物件

from pyarrow.fs import PyFileSystem, FSSpecHandler
pa_fs = PyFileSystem(FSSpecHandler(fs))

然後,FileSystem 的所有功能都可存取

# write data
with pa_fs.open_output_stream('mycontainer/pyarrowtest.dat') as stream:
   stream.write(b'data')

# read data
with pa_fs.open_input_stream('mycontainer/pyarrowtest.dat') as stream:
   print(stream.readall())
#b'data'

# read a partitioned dataset
ds.dataset("data/", filesystem=pa_fs)

將 Arrow 檔案系統與 fsspec 搭配使用#

Arrow FileSystem 介面具有有限且面向開發人員的 API 介面。這對於基本互動以及與 Arrow 的 IO 功能一起使用已足夠。另一方面,fsspec 介面提供了非常大的 API,其中包含許多輔助方法。如果您想使用這些方法,或者如果您需要與期望與 fsspec 相容的檔案系統物件的套件互動,則可以使用 fsspec 包裝 Arrow FileSystem 物件。

fsspec 版本 2021.09 開始,ArrowFSWrapper 可以用於此目的

>>> from pyarrow import fs
>>> local = fs.LocalFileSystem()
>>> from fsspec.implementations.arrow import ArrowFSWrapper
>>> local_fsspec = ArrowFSWrapper(local)

產生的物件現在具有與 fsspec 相容的介面,同時在底層由 Arrow FileSystem 支援。建立目錄和檔案以及列出內容的使用範例

>>> local_fsspec.mkdir("./test")
>>> local_fsspec.touch("./test/file.txt")
>>> local_fsspec.ls("./test/")
['./test/file.txt']

如需更多資訊,請參閱 fsspec 文件。