Parquet instructions
readTable, writeTable, and writeKeyValuePartitionedTable take their options as an instance of the ParquetInstructions class. Use this class to specify the layout of the Parquet files, the table definition, and how the files are compressed and encoded.
To read or write Parquet files on S3, S3-compatible stores, or Google Cloud Storage, pass an S3Instructions instance with the connection settings to the builder's setSpecialInstructions method.
ParquetInstructions
To create a ParquetInstructions instance, call ParquetInstructions.builder, which returns a ParquetInstructions.Builder instance. Call the builder's methods to set options, and then call build to create the ParquetInstructions instance.
For example, to specify that the source is a single Parquet file, use the following code:
You build instructions for writing the same way. A row group is a block of rows within a Parquet file. The following example writes the taxi table with Zstandard compression and splits the file into row groups of at most 10,000 rows:
ParquetInstructions.Builder methods
Some builder methods apply only when reading, some only when writing, and some to both.
Reading options
setFileLayout(fileLayout): Sets the Parquet file layout. If you don't call this method, Deephaven infers the layout. The availableParquetFileLayoutvalues are:ParquetFileLayout.SINGLE_FILE: A single Parquet file.ParquetFileLayout.FLAT_PARTITIONED: A single directory of Parquet files with no nested subdirectories.ParquetFileLayout.KV_PARTITIONED: A directory of Parquet files partitioned by key-value pairs.ParquetFileLayout.METADATA_PARTITIONED: The path of a_metadataor_common_metadatafile (the_metadatafile must exist in the same directory), or a directory containing a_metadatafile and an optional_common_metadatafile.
setIsLegacyParquet(isLegacyParquet): Sets whether to read aBINARYorFIXED_LEN_BYTE_ARRAYcolumn that has no Parquet logical type and no codec recorded in the file's Deephaven metadata asStringinstead ofbyte[]. The default isfalse.setIsRefreshing(isRefreshing): Sets whether the resulting table refreshes to pick up new files added to the source directory. A read with theSINGLE_FILEorMETADATA_PARTITIONEDlayout can't be refreshing.setUnsignedLongTarget(columnName, target): Sets the Deephaven type to read the specified unsigned 64-bit integer (UINT_64) column as. It applies only when Deephaven infers the table definition. You can't set two different targets for one column name. See ReadingUINT_64as alongfor how a table definition supplied withsetTableDefinitiontakes precedence and for write behavior. The availableUnsignedLongTargettargets are:UnsignedLongTarget.BIG_INTEGER: (default) Read the column asjava.math.BigInteger, which represents everyUINT_64value exactly.UnsignedLongTarget.LONG: Read the column aslong. Values greater than 263 - 1 have nolongrepresentation, so reading a page that contains one raises an error.UnsignedLongTarget.SIGNED_LONG: Read the column aslong, reinterpreting the bit pattern as signed. Values greater than 263 - 1 read as negative numbers, and 263 reads asNULL_LONG, which is indistinguishable from a null.
Writing options
addIndexColumns(indexColumns...)andaddAllIndexColumns(indexColumns): Add columns to persist together as indexes.addIndexColumnsadds one list of columns as one index.addAllIndexColumnstakes an iterable of lists, and each list is one index.- The write operation stores each index as a separate Parquet file in a
.dh_metadata/indexes/subdirectory of the directory that holds the data file. - If you call neither method, the default depends on the write method:
writeTablepersists the indexes that already exist on the source table.writeTablespersists the indexes of the first source table.writeKeyValuePartitionedTablewith a regular table persists the source table's existing indexes, except single-column indexes on a partitioning column. With aPartitionedTable, it writes no indexes.
- Use these methods to narrow the set of indexes to write, or to state the indexes expected on all sources.
- Indexes that are specified but missing are computed on demand.
- You can't add an index on a single partitioning column.
- To prevent the generation of index files, pass an empty iterable to
addAllIndexColumns.
- The write operation stores each index as a separate Parquet file in a
setBaseNameForPartitionedParquetData(baseNameForPartitionedParquetData): Sets the base name of the files written for partitioned Parquet data. The default is{uuid}. The base name can contain these tokens:{i}: An automatically incremented integer.{uuid}: A random UUID.{partitions}: The partition values as underscore-delimitedkey=valuepairs. For example,{partitions}-tablewith partitioning columnsPC1andPC2produces a file named likePC1=partition1_PC2=partitionA-table.parquet.
setCompressionCodecName(compressionCodecName): Sets the name of the compression codec used when writing Parquet files. The codec applies to every column in the file and affects write speed and file size. The options are:SNAPPY: (default) Aims for high speed and a reasonable amount of compression. Based on Google's Snappy compression format.UNCOMPRESSED: The output is not compressed.LZ4_RAW: A codec based on the LZ4 block format.LZO: Compression codec based on or interoperable with the LZO compression library.GZIP: Compression codec based on the GZIP format defined by RFC 1952. This is a different format from the closely related zlib and deflate formats.ZSTD: Compression codec with a high compression ratio based on the Zstandard format defined by RFC 8478.BROTLI: Compression codec based on Brotli, offering high compression ratios.- Deephaven doesn't include a Brotli codec. To use this option, add a Brotli codec (
org.apache.hadoop.io.compress.BrotliCodec) to the server classpath. - Without a Brotli codec on the classpath, the write fails with a
Failed to find CompressionCodecerror.
- Deephaven doesn't include a Brotli codec. To use this option, add a Brotli codec (
LZ4: Deprecated. UseLZ4_RAWinstead.
setFieldId(columnName, fieldId): Sets the Parquet field ID written for the specified column. Most users don't need to set field IDs.setGenerateMetadataFiles(generateMetadataFiles): Sets whether to generate_metadataand_common_metadatafiles while writing Parquet files.setMaximumDictionaryKeys(maximumDictionaryKeys): Sets the maximum number of unique keys the writer adds to a column's dictionary before it switches to non-dictionary encoding. The default is 1048576, the value ofParquetInstructions.DEFAULT_MAXIMUM_DICTIONARY_KEYS.- The writer applies this setting only to
Stringcolumns and columns ofStringarrays or vectors. - The writer ignores the setting for a column where
useDictionaryis set totrue.
- The writer applies this setting only to
setMaximumDictionarySize(maximumDictionarySize): Sets the maximum number of bytes the writer adds to a column's dictionary before it switches to non-dictionary encoding. The default is 1048576, the value ofParquetInstructions.DEFAULT_MAXIMUM_DICTIONARY_SIZE.- The writer applies this setting only to
Stringcolumns and columns ofStringarrays or vectors. - The writer ignores the setting for a column where
useDictionaryis set totrue.
- The writer applies this setting only to
setOnWriteCompleted(onWriteCompleted): Sets a callback invoked after each Parquet data file is written, excluding index and metadata files.setRowGroupInfo(rowGroupInfo): Sets how the writer splits the table into row groups. The available options are:RowGroupInfo.singleGroup: The defaultRowGroupInfoimplementation. All data is written within a single row group.RowGroupInfo.maxRows(maxRows): Splits the table into row groups of no more thanmaxRowsrows each.RowGroupInfo.maxGroups(numRowGroups): Splits the table into the requested number of row groups of nearly equal size. If the row count isn't evenly divisible by the number of row groups, some row groups contain one fewer row than others.RowGroupInfo.byGroups(groups): Splits each unique group into a row group.RowGroupInfo.byGroups(maxRows, groups): Splits each unique group into a row group, and splits any group with more thanmaxRowsrows further, asRowGroupInfo.maxRows(maxRows)does.- For both
byGroupsoptions, the write throws an exception if the values of the grouping columns aren't contiguous in the input table.
setTargetPageSize(targetPageSize): Sets the target size, in bytes, of each data page the writer produces. The default is 65536, the value ofParquetInstructions.DEFAULT_TARGET_PAGE_SIZE.- You can override the default with the
Parquet.defaultTargetPageSizeconfiguration property. - The value must be at least the
Parquet.minTargetPageSizeconfiguration property, which defaults to 2048.
- You can override the default with the
useDictionary(columnName, useDictionary): Sets a hint that the writer should keep dictionary encoding for this column.- The writer already tries dictionary encoding for every
Stringcolumn and every column ofStringarrays or vectors. - Setting the hint to
trueremoves thesetMaximumDictionaryKeysandsetMaximumDictionarySizelimits for the column, so the writer never falls back to non-dictionary encoding. The writer holds the column's dictionary and encoded pages in memory until it finishes the column, so setting the hint on a high-cardinalityStringcolumn can exhaust the JVM heap. Set it only when the number of unique values is bounded. - The writer ignores this hint for other column types.
- The writer already tries dictionary encoding for every
Reading and writing options
addColumnCodec(columnName, codecName): Maps a column to a column codec, the class Deephaven uses to convert that column's values to and from bytes.codecNameis the codec's class name.addColumnCodec(columnName, codecName, codecArgs): Adds a column codec mapping between the provided column name and codec name, with arguments for the codec.addColumnNameMapping(parquetColumnName, columnName): Adds a column name mapping between the provided Parquet column name and Deephaven column name.setSpecialInstructions(specialInstructions): Sets special instructions for reading or writing Parquet files at an S3 URI (s3://,s3a://, ors3n://, including S3-compatible stores) or a Google Cloud Storage URI (gs://). Pass anS3Instructionsinstance.setTableDefinition(tableDefinition): Sets the table definition to use instead of the one inferred from the Parquet files when reading, or from the source table when writing.
Other builder methods
build: Builds theParquetInstructionsinstance.new ParquetInstructions.Builder(existingInstructions): Creates a builder pre-populated with the settings of an existingParquetInstructionsinstance.getTakenNames: Returns the set of Deephaven column names that already have per-column settings on this builder. The per-column settings come fromaddColumnNameMapping,addColumnCodec,setFieldId,setUnsignedLongTarget, anduseDictionary.
The builder also has methods for integrations such as Iceberg, including setColumnResolverFactory. Users don't typically call these methods, so this page doesn't list them.
ParquetInstructions methods
A ParquetInstructions instance has an accessor for each builder setting listed above:
| Builder method | ParquetInstructions accessor |
|---|---|
addAllIndexColumns, addIndexColumns | getIndexColumns |
addColumnCodec | getCodecName, getCodecArgs |
addColumnNameMapping | getColumnNameFromParquetColumnName |
setBaseNameForPartitionedParquetData | baseNameForPartitionedParquetData |
setCompressionCodecName | getCompressionCodecName |
setFieldId | getFieldId |
setFileLayout | getFileLayout |
setGenerateMetadataFiles | generateMetadataFiles |
setIsLegacyParquet | isLegacyParquet |
setIsRefreshing | isRefreshing |
setMaximumDictionaryKeys | getMaximumDictionaryKeys |
setMaximumDictionarySize | getMaximumDictionarySize |
setOnWriteCompleted | onWriteCompleted |
setRowGroupInfo | getRowGroupInfo |
setSpecialInstructions | getSpecialInstructions |
setTableDefinition | getTableDefinition |
setTargetPageSize | getTargetPageSize |
setUnsignedLongTarget | getUnsignedLongTarget |
useDictionary | useDictionary |
Some accessors take or return more than their names suggest:
getCodecName,getCodecArgs,getFieldId,getUnsignedLongTarget, anduseDictionarytake acolumnNameargument.getColumnNameFromParquetColumnNametakes aparquetColumnNameargument.getRowGroupInforeturns aRowGroupInfo.getUnsignedLongTargetreturns an emptyOptionalif no target was set.useDictionaryreturnsfalseif no hint was set.
The ParquetInstructions class also has the following methods:
builder: Returns a newParquetInstructions.Builderinstance.getColumnNameFromParquetColumnNameOrDefault(parquetColumnName): Returns the column name in the Deephaven table corresponding to the specified Parquet column name, or the Parquet column name if no mapping exists.getParquetColumnNameFromColumnNameOrDefault(columnName): Returns the Parquet column name corresponding to the specified column name, or the column name if no mapping exists.withLayout(fileLayout): Returns a newParquetInstructionsinstance with the suppliedParquetFileLayout.withTableDefinition(tableDefinition): Returns a newParquetInstructionsinstance with the supplied table definition.withTableDefinitionAndLayout(tableDefinition, fileLayout): Returns a newParquetInstructionsinstance with the supplied table definition andParquetFileLayout.
S3Instructions
To read Parquet files from or write them to S3, S3-compatible stores, or Google Cloud Storage, pass an S3Instructions instance to the setSpecialInstructions method of ParquetInstructions.Builder. Create the instance with S3Instructions.builder, call the builder's methods to set options, and then call build:
For a complete example that reads from S3, see Import Parquet files.
S3Instructions methods
Set each of the following options with the S3Instructions.Builder method of the same name, and read it back with the S3Instructions method of the same name:
configFilePath: The path to the AWS configuration file used to configure the default region, credentials, and other settings. If this is not set, the AWS SDK picks the file from theaws.configFilesystem property, theAWS_CONFIG_FILEenvironment variable, or{user.home}/.aws/config.connectionTimeout: ADurationrepresenting the amount of time to wait for a successful S3 connection before timing out. The default is 2 seconds.credentials: TheCredentialsto use for reading and writing files. Options are:Credentials.resolving: (default) Use profile credentials if a profile name, configuration file path, or credentials file path is set. Otherwise, look in the AWS SDK's default locations and fall back to anonymous credentials.Credentials.anonymous: Use anonymous credentials.Credentials.basic(accessKeyId, secretAccessKey): Use basic credentials with the specified access key ID and secret access key.Credentials.defaultCredentials: Use the AWS SDK's default credentials provider.Credentials.profile: Use credentials from the AWS configuration and credentials files.Credentials.session(accessKeyId, secretAccessKey, sessionToken): Use temporary credentials, such as those from AWS STS.
credentialsFilePath: The path to the AWS credentials file used to configure the default region, credentials, and other settings. If this is not set, the AWS SDK picks the file from theaws.credentialsFilesystem property, theAWS_CREDENTIALS_FILEenvironment variable, or{user.home}/.aws/credentials.endpointOverride: The endpoint to connect to. Set it when connecting to a non-AWS, S3-compatible API. Callers connecting to AWS don't typically need it. By default, no endpoint override is set.fragmentSize: The maximum byte size of each fragment to read from S3. The default is 65536, and the minimum is 8192.maxConcurrentRequests: The maximum number of concurrent requests to make to S3. The default is 256.numConcurrentWriteParts: The maximum number of parts that can be uploaded concurrently when writing to S3 before the write blocks. The default is 64. The value can't exceedmaxConcurrentRequests. Each write can hold up to this many parts in heap memory, eachwritePartSizebytes. The defaults allow about 640 MiB for one write, so raising either value increases heap use.profileName: The AWS profile used to configure the default region, credentials, and other settings. If this is not set, the AWS SDK picks the profile from theaws.profilesystem property, theAWS_PROFILEenvironment variable, ordefault.readAheadCount: The number of fragments to read asynchronously ahead of the fragment currently being read. The default is 32.readTimeout: The amount of time to wait for a fragment read to complete before timing out. The default is 2 seconds.regionName: The region name of the AWS S3 bucket where the Parquet data exists. If you don't set it, the AWS SDK picks the region from the first of these sources that provides one:- The
aws.regionsystem property - The
AWS_REGIONenvironment variable - The
{user.home}/.aws/credentialsor{user.home}/.aws/configfile - The EC2 metadata service, when running in EC2
- If none of these sources provides a region, or the region is wrong for the bucket, Deephaven derives the correct region with one additional request
- The
writePartSize: The size of each part (in bytes) to upload when writing to S3. The default is 10485760, and the minimum is 5242880.writeTimeout: The amount of time to wait for a fragment write to complete before timing out. The default is 2 seconds.
A built S3Instructions instance also has the withEndpointOverride(endpointOverride) method, which returns a copy of the instance with the supplied endpoint override.