使用 turbodbc 將關聯式資料庫連接到 Apache Arrow 世界
已發布 2017年6月16日
作者 Michael König (MathMagique)
Michael König 是 turbodbc 專案 的主要開發者
Apache Arrow 專案旨在成為面向列式資料處理系統的通用資料層,在更廣泛的層面上,既不產生序列化成本,又不損害效能。雖然關聯式資料庫在採用 Apache Arrow 方面仍然落後,但 Python 資料庫模組 turbodbc 使用更舊、更專業的資料交換層:ODBC,為這些資料庫帶來了 Apache Arrow 支援。
ODBC 是一種資料庫介面,為開發人員提供了以逐行或逐列方式傳輸資料的選項。先前的 Python ODBC 模組通常使用逐行方法,並且經常以重複的資料庫往返次數來換取簡化的緩衝區處理。這使得它們不太適合資料密集型應用程式,尤其是在與現代列式分析資料庫介接時。
相比之下,turbodbc 從一開始就被設計為利用列式資料處理。自然而然地,這意味著使用 ODBC API 的列式部分。然而,同樣重要的是找到向 Python 使用者提供列式資料的新方法,這些方法要超越 Python 的 PEP 249 所要求的逐行 API 的功能。Turbodbc 採用了 Apache Arrow 來完成這項任務,並在最近發布的 2.0.0 版本中實現。
>>> from turbodbc import connect
>>> connection = connect(dsn="My columnar database")
>>> cursor = connection.cursor()
>>> cursor.execute("SELECT some_integers, some_strings FROM my_table")
>>> cursor.fetchallarrow()
pyarrow.Table
some_integers: int64
some_strings: string
透過這個新增加的功能,典型 SELECT 查詢的結果集資料流程如下所示
- 資料庫準備結果集,並使用逐行或逐列儲存將其公開給 ODBC 驅動程式。
- Turbodbc 讓 ODBC 驅動程式將結果集的區塊寫入列式緩衝區。
- 這些緩衝區會公開給 turbodbc 的 Apache Arrow 前端。這個前端將建立一個 Arrow 表格,並填入緩衝的值。
- 重複先前的步驟,直到檢索到整個結果集。
實際上,有可能實現以下理想情況:一個 64 位元整數列以一個連續的記憶體區塊儲存在列式資料庫中。大量的 64 位元整數透過網路傳輸,ODBC 驅動程式直接將其寫入 turbodbc 的 64 位元整數緩衝區。Arrow 前端透過將整個 64 位元緩衝區複製到 Arrow 表格的 64 位元整數列的可用部分來累積這些值。
將資料從資料庫移動到 Arrow 表格,從而提供給 Python 使用者,可以像複製記憶體區塊一樣簡單,每次複製相當於數十萬行的兆位元組。沒有序列化和轉換邏輯,使得這個過程非常有效率。
一旦資料儲存在 Arrow 表格中,Python 使用者就可以繼續進行一些實際工作。他們可以將其轉換為 Pandas DataFrame 以進行資料分析(使用快速的 table.to_pandas()
),將其傳遞給其他資料處理系統,例如 Apache Spark 或 Apache Impala (孵化中),或以 Apache Parquet 檔案格式儲存。這樣,非 Python 系統就可以有效地與關聯式資料庫連接。
未來,turbodbc 的 Arrow 支援將會擴展到使用更複雜的功能,例如 字典編碼 字串欄位。我們也計畫在可能的情況下選擇小於 64 位元的 資料類型。最後但並非最不重要的是,Arrow 支援將擴展到涵蓋資料流程的反向,以便 Python 使用者可以快速將 Arrow 表格插入到關聯式資料庫中。
如果您想了解更多關於 turbodbc 的資訊,請查看 GitHub 專案 和 專案文件。如果您想了解更多關於 turbodbc 如何實作具體細節的資訊,請查看 「turbodbc 的製作」 系列文章的 第一部分 和 第二部分,該系列文章位於 Blue Yonder 的技術部落格。