The simplest way to query parquet files is to use the [`SessionContext::read_parquet`] API For more control, you can use the lower level [`ListingOptions`] and [`ListingTable`] APIS This example shows how to use relative and absolute paths. [`ListingTable`]: datafusion::datasource::listing::ListingTable
()
| 111 | /// |
| 112 | /// [`ListingTable`]: datafusion::datasource::listing::ListingTable |
| 113 | async fn query_parquet() -> Result<()> { |
| 114 | // create local execution context |
| 115 | let ctx = SessionContext::new(); |
| 116 | |
| 117 | // Convert the CSV input into a temporary Parquet directory for querying |
| 118 | let dataset = ExampleDataset::Cars; |
| 119 | let parquet_temp = write_csv_to_parquet(&ctx, &dataset.path()).await?; |
| 120 | |
| 121 | // Configure listing options |
| 122 | let file_format = ParquetFormat::default().with_enable_pruning(true); |
| 123 | let listing_options = |
| 124 | ListingOptions::new(Arc::new(file_format)).with_file_extension(".parquet"); |
| 125 | |
| 126 | let table_path = parquet_temp.file_uri()?; |
| 127 | |
| 128 | // First example were we use an absolute path, which requires no additional setup. |
| 129 | ctx.register_listing_table( |
| 130 | "my_table", |
| 131 | &table_path, |
| 132 | listing_options.clone(), |
| 133 | None, |
| 134 | None, |
| 135 | ) |
| 136 | .await?; |
| 137 | |
| 138 | // execute the query |
| 139 | let df = ctx |
| 140 | .sql( |
| 141 | "SELECT * \ |
| 142 | FROM my_table \ |
| 143 | ORDER BY speed \ |
| 144 | LIMIT 1", |
| 145 | ) |
| 146 | .await?; |
| 147 | |
| 148 | // print the results |
| 149 | let results = df.collect().await?; |
| 150 | assert_batches_eq!( |
| 151 | [ |
| 152 | "+-----+-------+---------------------+", |
| 153 | "| car | speed | time |", |
| 154 | "+-----+-------+---------------------+", |
| 155 | "| red | 0.0 | 1996-04-12T12:05:15 |", |
| 156 | "+-----+-------+---------------------+", |
| 157 | ], |
| 158 | &results |
| 159 | ); |
| 160 | |
| 161 | // Second example where we change the current working directory and explicitly |
| 162 | // register a local filesystem object store. This demonstrates how listing tables |
| 163 | // resolve paths via an ObjectStore, even when using filesystem-backed data. |
| 164 | let cur_dir = std::env::current_dir()?; |
| 165 | let test_data_path_parent = parquet_temp |
| 166 | .tmp_dir |
| 167 | .path() |
| 168 | .parent() |
| 169 | .ok_or(exec_datafusion_err!("test_data path needs a parent"))?; |
| 170 |
no test coverage detected
searching dependent graphs…