| # Licensed to the Apache Software Foundation (ASF) under one | |
| # or more contributor license agreements. See the NOTICE file | |
| # distributed with this work for additional information | |
| # regarding copyright ownership. The ASF licenses this file | |
| # to you under the Apache License, Version 2.0 (the | |
| # "License"); you may not use this file except in compliance | |
| # with the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, | |
| # software distributed under the License is distributed on an | |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| # KIND, either express or implied. See the License for the | |
| # specific language governing permissions and limitations | |
| # under the License. | |
| """ | |
| This is a utility function that will consumer the data generated by dbgen from TPC-H and convert | |
| it into a parquet file with the column names as expected by the TPC-H specification. It assumes | |
| the data generated resides in a path ../../benchmarks/tpch/data relative to the current file, | |
| as will be generated by the script provided in this repository. | |
| """ | |
| from pathlib import Path | |
| import datafusion | |
| import pyarrow as pa | |
| ctx = datafusion.SessionContext() | |
| all_schemas = {} | |
| all_schemas["customer"] = [ | |
| ("C_CUSTKEY", pa.int64()), | |
| ("C_NAME", pa.string()), | |
| ("C_ADDRESS", pa.string()), | |
| ("C_NATIONKEY", pa.int64()), | |
| ("C_PHONE", pa.string()), | |
| ("C_ACCTBAL", pa.decimal128(15, 2)), | |
| ("C_MKTSEGMENT", pa.string()), | |
| ("C_COMMENT", pa.string()), | |
| ] | |
| all_schemas["lineitem"] = [ | |
| ("L_ORDERKEY", pa.int64()), | |
| ("L_PARTKEY", pa.int64()), | |
| ("L_SUPPKEY", pa.int64()), | |
| ("L_LINENUMBER", pa.int32()), | |
| ("L_QUANTITY", pa.decimal128(15, 2)), | |
| ("L_EXTENDEDPRICE", pa.decimal128(15, 2)), | |
| ("L_DISCOUNT", pa.decimal128(15, 2)), | |
| ("L_TAX", pa.decimal128(15, 2)), | |
| ("L_RETURNFLAG", pa.string()), | |
| ("L_LINESTATUS", pa.string()), | |
| ("L_SHIPDATE", pa.date32()), | |
| ("L_COMMITDATE", pa.date32()), | |
| ("L_RECEIPTDATE", pa.date32()), | |
| ("L_SHIPINSTRUCT", pa.string()), | |
| ("L_SHIPMODE", pa.string()), | |
| ("L_COMMENT", pa.string()), | |
| ] | |
| all_schemas["nation"] = [ | |
| ("N_NATIONKEY", pa.int64()), | |
| ("N_NAME", pa.string()), | |
| ("N_REGIONKEY", pa.int64()), | |
| ("N_COMMENT", pa.string()), | |
| ] | |
| all_schemas["orders"] = [ | |
| ("O_ORDERKEY", pa.int64()), | |
| ("O_CUSTKEY", pa.int64()), | |
| ("O_ORDERSTATUS", pa.string()), | |
| ("O_TOTALPRICE", pa.decimal128(15, 2)), | |
| ("O_ORDERDATE", pa.date32()), | |
| ("O_ORDERPRIORITY", pa.string()), | |
| ("O_CLERK", pa.string()), | |
| ("O_SHIPPRIORITY", pa.int32()), | |
| ("O_COMMENT", pa.string()), | |
| ] | |
| all_schemas["part"] = [ | |
| ("P_PARTKEY", pa.int64()), | |
| ("P_NAME", pa.string()), | |
| ("P_MFGR", pa.string()), | |
| ("P_BRAND", pa.string()), | |
| ("P_TYPE", pa.string()), | |
| ("P_SIZE", pa.int32()), | |
| ("P_CONTAINER", pa.string()), | |
| ("P_RETAILPRICE", pa.decimal128(15, 2)), | |
| ("P_COMMENT", pa.string()), | |
| ] | |
| all_schemas["partsupp"] = [ | |
| ("PS_PARTKEY", pa.int64()), | |
| ("PS_SUPPKEY", pa.int64()), | |
| ("PS_AVAILQTY", pa.int32()), | |
| ("PS_SUPPLYCOST", pa.decimal128(15, 2)), | |
| ("PS_COMMENT", pa.string()), | |
| ] | |
| all_schemas["region"] = [ | |
| ("r_REGIONKEY", pa.int64()), | |
| ("r_NAME", pa.string()), | |
| ("r_COMMENT", pa.string()), | |
| ] | |
| all_schemas["supplier"] = [ | |
| ("S_SUPPKEY", pa.int64()), | |
| ("S_NAME", pa.string()), | |
| ("S_ADDRESS", pa.string()), | |
| ("S_NATIONKEY", pa.int32()), | |
| ("S_PHONE", pa.string()), | |
| ("S_ACCTBAL", pa.decimal128(15, 2)), | |
| ("S_COMMENT", pa.string()), | |
| ] | |
| curr_dir = Path(__file__).resolve().parent | |
| for filename, curr_schema_val in all_schemas.items(): | |
| # For convenience, go ahead and convert the schema column names to lowercase | |
| curr_schema = [(s[0].lower(), s[1]) for s in curr_schema_val] | |
| # Pre-collect the output columns so we can ignore the null field we add | |
| # in to handle the trailing | in the file | |
| output_cols = [r[0] for r in curr_schema] | |
| curr_schema = [pa.field(r[0], r[1], nullable=False) for r in curr_schema] | |
| # Trailing | requires extra field for in processing | |
| curr_schema.append(("some_null", pa.null())) | |
| schema = pa.schema(curr_schema) | |
| source_file = (curr_dir / f"../../benchmarks/tpch/data/{filename}.csv").resolve() | |
| dest_file = (curr_dir / f"./data/{filename}.parquet").resolve() | |
| df = ctx.read_csv(source_file, schema=schema, has_header=False, delimiter="|") | |
| df = df.select(*output_cols) | |
| df.write_parquet(dest_file, compression="snappy") |