Databricks(Spark)にてPythonによりテーブルのサイズを確認する方法

## 概要
Databricks(Spark)にてPythonによりテーブルのサイズを確認する方法を紹介します。

DatabricksのドキュメントにてScalaでテーブルサイズを確認する方法が紹介されており、Python（PySpark）に置き換えました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/41d97940-4d05-351b-301d-09ab4cd8ea41.png)
引用元：[テーブルのサイズの検索-Azure Databricks - Workspace | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/databricks/kb/sql/find-size-of-table)

Delta lake形式とその他の形式で取得方法が異なり、Delta Lake形式では`describe detail`を利用するように変更しております。おそらくOSSのdelta lakeを利用している場合にもデータが取得できるはずです。


## Delta Lake形式におけるデータフレーム・テーブルのサイズを確認する方法
### Scalaでの実行例

```scala
%scala
import com.databricks.sql.transaction.tahoe._
val table_size = DeltaLog.forTable(spark, "dbfs:/tmp/qiita/flights/summary-data/delta").snapshot.sizeInBytes
println(s"Total file size (bytes): ${table_size}")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4a29e35c-c6ec-b85c-66a9-b484e61bfeca.png)


### テーブル名を指定する方法

```python
# テーブル名を指定する方法
table_name = 'flights_summary_data'
table_size = spark.sql(f'describe detail {table_name}').select('sizeInBytes').first()[0]
print(f"Total file size (bytes): {table_size}")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/73cc4118-a820-07df-db63-b284a44102d9.png)


### テーブルのファイルパスを指定する方法

```python
# テーブルのファイルパスを指定する方法
table_location = '"dbfs:/tmp/qiita/flights/summary-data/delta"'
table_size = spark.sql(f'describe detail {table_location}').select('sizeInBytes').first()[0]
print(f"Total file size (bytes): {table_size}")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4fb2c458-3d11-75f1-f103-e29c3d518c71.png)


## Delta Lake形式以外（Parquet・CSV・Json等）におけるデータフレーム・テーブルのサイズを確認する方法
### Scalaでの実行例

```scala
%scala
spark.read.table("flights_summary_data_parquet").queryExecution.analyzed.stats.sizeInBytes
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/64b4c9f2-2167-753c-d944-0aea5e03b630.png)


### テーブル名を指定する方法

```python
# テーブル名を指定する方法
table_name = 'flights_summary_data_parquet'
table_size = spark.read.table(table_name)._jdf.queryExecution().analyzed().stats().sizeInBytes()
print(f"Total file size (bytes): {table_size}")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9cc7955d-0603-05c1-9a31-11118a395287.png)

### テーブルのファイルパスを指定する方法

```python
# テーブルのファイルパスを指定する方法
table_location = "/databricks-datasets/learning-spark-v2/flights/summary-data/parquet/*"

df = (spark
        .read
        .format("parquet")
        .option("inferSchema", "True")
        .load(table_location)
     )

table_size = df._jdf.queryExecution().analyzed().stats().sizeInBytes()
print(f"Total file size (bytes): {table_size}")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7e1a4da8-8983-335a-32ac-1ab21556e2ec.png)

## その他
### CSV形式のデータフレームのサイズを確認する方法

```python
# CSVファイルのディレクトリと合計サイズを表示
file_list =dbutils.fs.ls("/databricks-datasets/learning-spark-v2/flights/summary-data/csv")
display(file_list)
spark.createDataFrame(file_list).groupBy().sum('size').display()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f16f2b60-2a03-cd00-2d22-30e03be9022b.png)

```python
# テーブルのファイルパスを指定する方法
table_location = "/databricks-datasets/learning-spark-v2/flights/summary-data/csv/*"

schema = """
  DEST_COUNTRY_NAME STRING
  ,ORIGIN_COUNTRY_NAME STRING
  ,count INT
"""

df = (spark
        .read
        .format("csv")
        .schema(schema)
        .option("header", "true")
        .option("inferSchema", "False")
        .load(table_location)
     )
table_size = df._jdf.queryExecution().analyzed().stats().sizeInBytes()
print(f"Total file size (bytes): {table_size}")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c2256b69-d14d-7270-f292-bb2c5bd43651.png)