parquet-go is a pure-Go library for reading and writing Apache Parquet files.
- Read and write flat and nested Parquet data.
- Use Go struct tags, JSON schema, CSV metadata, or Arrow schemas.
- Work with local files, memory buffers, cloud object stores, HDFS, HTTP, and GoCloud CDK blobs.
- Configure readers and writers with per-instance functional options.
- Use modern Parquet features including Data Page V2, CRC page checksums, modular encryption, bloom filters, and newer logical types.
- Convert geospatial logical types with configurable GeoJSON, hex, base64, or hybrid JSON output.
- Installation
- Quick Start
- Configuration
- Schema Definition
- Type System
- Encoding Support
- Compression Support
- Readers and Writers
- File Sources
- Advanced Features
- Examples
- Documentation
- Contributing
- License
go get github.com/hangxie/parquet-go/v3package main
import (
"log"
"github.com/hangxie/parquet-go/v3/source/local"
"github.com/hangxie/parquet-go/v3/writer"
)
type Student struct {
Name string `parquet:"name=name, type=BYTE_ARRAY, logicaltype=STRING, encoding=PLAIN_DICTIONARY"`
Age int32 `parquet:"name=age, type=INT32"`
ID int64 `parquet:"name=id, type=INT64"`
Weight float32 `parquet:"name=weight, type=FLOAT"`
Sex bool `parquet:"name=sex, type=BOOLEAN"`
}
func main() {
fw, err := local.NewLocalFileWriter("output.parquet")
if err != nil {
log.Fatal("can't create file: ", err)
}
defer fw.Close()
pw, err := writer.NewParquetWriter(fw, new(Student))
if err != nil {
log.Fatal("can't create parquet writer: ", err)
}
for i := 0; i < 10; i++ {
stu := Student{
Name: "StudentName",
Age: int32(20 + i%5),
ID: int64(i),
Weight: float32(50.0 + float32(i)*0.1),
Sex: i%2 == 0,
}
if err = pw.Write(stu); err != nil {
log.Fatal("write error: ", err)
}
}
if err = pw.WriteStop(); err != nil {
log.Fatal("writestop error: ", err)
}
}package main
import (
"log"
"github.com/hangxie/parquet-go/v3/reader"
"github.com/hangxie/parquet-go/v3/source/local"
)
type Student struct {
Name string `parquet:"name=name, type=BYTE_ARRAY, logicaltype=STRING"`
Age int32 `parquet:"name=age, type=INT32"`
ID int64 `parquet:"name=id, type=INT64"`
Weight float32 `parquet:"name=weight, type=FLOAT"`
Sex bool `parquet:"name=sex, type=BOOLEAN"`
}
func main() {
fr, err := local.NewLocalFileReader("output.parquet")
if err != nil {
log.Fatal("can't open file: ", err)
}
defer fr.Close()
pr, err := reader.NewParquetReader(fr, new(Student), reader.WithNP(4))
if err != nil {
log.Fatal("can't create parquet reader: ", err)
}
defer func() { _ = pr.ReadStop() }()
students := make([]Student, int(pr.GetNumRows()))
if err = pr.Read(&students); err != nil {
log.Fatal("read error: ", err)
}
for _, stu := range students {
log.Printf("%+v\n", stu)
}
}Readers and writers are configured per instance by passing functional options to their constructors. This keeps independent readers and writers safe to use with different settings in the same process. Options are construction inputs, not a public API for mutating an already-created reader or writer.
Common writer options:
writer.WithNPwriter.WithPageSizewriter.WithRowGroupSizewriter.WithCompressionCodecwriter.WithCompressionLevelwriter.WithDataPageVersionwriter.WithWriteCRC
Common reader options:
reader.WithNPreader.WithCaseInsensitivereader.WithCRCMode
Encryption-related options are covered in Encryption.
Reader footers expose schema and column paths as stored in the Parquet file. Use ParquetReader.InternalFooter() when a tool needs a converted footer with internal Go schema names.
Only fields included in the schema are written. Struct fields must be exported.
type Student struct {
Name string `parquet:"name=name, type=BYTE_ARRAY, logicaltype=STRING, encoding=PLAIN_DICTIONARY"`
Age int32 `parquet:"name=age, type=INT32, encoding=PLAIN"`
ID int64 `parquet:"name=id, type=INT64"`
Weight float32 `parquet:"name=weight, type=FLOAT"`
Sex bool `parquet:"name=sex, type=BOOLEAN"`
}jsonSchema := `{
"Tag": "name=parquet_go_root, repetitiontype=REQUIRED",
"Fields": [
{"Tag": "name=name, type=BYTE_ARRAY, logicaltype=STRING, repetitiontype=REQUIRED"},
{"Tag": "name=age, type=INT32, repetitiontype=REQUIRED"}
]
}`md := []string{
"name=Name, type=BYTE_ARRAY, logicaltype=STRING, encoding=PLAIN_DICTIONARY",
"name=Age, type=INT32",
}schema := arrow.NewSchema(
[]arrow.Field{
{Name: "int64", Type: arrow.PrimitiveTypes.Int64},
{Name: "float64", Type: arrow.PrimitiveTypes.Float64},
{Name: "float16", Type: arrow.FixedWidthTypes.Float16},
},
nil,
)Schema notes:
InNameis the Go field name.ExNameis the Parquet field name.- Avoid field names that differ only by first-letter case.
PARGO_PREFIX_is reserved and should not be used as a field prefix.- Column paths separate their components with
common.ParGoPathDelimiter(\x01); build a path withcommon.PathToStr..is an ordinary character in a field name, never a separator, so a name may contain.(it stays a single path component). This applies to every path-taking API, includingParquetReader.ReadPartial,ReadColumnByPath,SkipRowsByPath,BloomFilterCheck,reader.WithColumnKey, andwriter.WithColumnEncrypted. - Arrow
Float16fields are written asFIXED_LEN_BYTE_ARRAYwithlength=2andlogicaltype=FLOAT16; generic Parquet reads expose them as raw two-byte strings. Usetypes.ConvertFloat16LogicalValuewhen afloat32value is needed. FLOAT16 statistics and column indexes use the Parquet FLOAT16 total ordering. UNKNOWNcolumns represent always-null columns per the Parquet spec. The Go field must be*int32withrepetitiontype=OPTIONAL. The writer rejects any non-nil value with an error. For a well-formed file every read returnsnil; a malformed file that stores a non-null INT32 value in an UNKNOWN column will have that value returned as-is.
| Primitive Type | Go Type |
|---|---|
BOOLEAN |
bool |
INT32 |
int32 |
INT64 |
int64 |
INT96 (deprecated) |
string |
FLOAT |
float32 |
DOUBLE |
float64 |
BYTE_ARRAY |
string |
FIXED_LEN_BYTE_ARRAY |
string |
| Logical Type | Primitive Type | Go Type |
|---|---|---|
UTF8 |
BYTE_ARRAY |
string |
INT_8 |
INT32 |
int32 |
INT_16 |
INT32 |
int32 |
INT_32 |
INT32 |
int32 |
INT_64 |
INT64 |
int64 |
UINT_8 |
INT32 |
int32 |
UINT_16 |
INT32 |
int32 |
UINT_32 |
INT32 |
int32 |
UINT_64 |
INT64 |
int64 |
DATE |
INT32 |
int32 |
TIME_MILLIS |
INT32 |
int32 |
TIME_MICROS |
INT64 |
int64 |
TIMESTAMP_MILLIS |
INT64 |
int64 |
TIMESTAMP_MICROS |
INT64 |
int64 |
INTERVAL |
FIXED_LEN_BYTE_ARRAY |
string |
DECIMAL |
INT32, INT64, FIXED_LEN_BYTE_ARRAY, BYTE_ARRAY |
int32, int64, string, string |
UUID |
FIXED_LEN_BYTE_ARRAY |
string |
FLOAT16 |
FIXED_LEN_BYTE_ARRAY |
string |
UNKNOWN |
INT32 |
*int32 (always nil) |
GEOMETRY |
BYTE_ARRAY |
string |
GEOGRAPHY |
BYTE_ARRAY |
string |
JSON |
BYTE_ARRAY |
string |
BSON |
BYTE_ARRAY |
string |
LIST |
- | slice |
MAP |
- | map |
Type aliases are supported, for example type MyString string, when the base type follows the table. Conversion utilities are available in types/converter.go.
| Repetition Type | Go Declaration | Description |
|---|---|---|
REQUIRED |
V1 int32 with tag parquet:"name=v1, type=INT32" |
Standard required field |
OPTIONAL |
V1 *int32 with tag parquet:"name=v1, type=INT32" |
Use a pointer for optional fields |
REPEATED |
V1 []int32 with tag parquet:"name=v1, type=INT32, repetitiontype=REPEATED" |
Use a slice with repetitiontype=REPEATED |
LIST and REPEATED are different in the Parquet format. Prefer LIST for list data. Standard and non-standard LIST/MAP layouts are both supported.
| Encoding | Types | Read | Write |
|---|---|---|---|
PLAIN |
All types | Y | Y |
PLAIN_DICTIONARY |
All types | Y | Y |
RLE_DICTIONARY |
All types | Y | Y |
DELTA_BINARY_PACKED |
Integer types | Y | Y |
DELTA_BYTE_ARRAY |
BYTE_ARRAY, UTF8 |
Y | Y |
DELTA_LENGTH_BYTE_ARRAY |
BYTE_ARRAY, UTF8 |
Y | Y |
BYTE_STREAM_SPLIT |
INT32, INT64, FIXED_LEN_BYTE_ARRAY |
Y | Y |
BIT_PACKED |
Boolean, integer | Y | Y |
Encoding notes:
- For maximum compatibility, use
PLAINandPLAIN_DICTIONARY. - Avoid dictionary encoding for high-cardinality fields because dictionaries can consume significant memory.
- Use
omitstats=truein a field tag to skip statistics for large array fields. - Whenever min/max statistics are available, the current
min_value/max_valuefields are written. The deprecatedmin/maxfields (PARQUET-251) are limited to signed sort orders; for unsigned-ordered columns (e.g.BYTE_ARRAY/UTF8 and unsigned integer logical types) they are omitted so legacy readers do not misinterpret them.
| Compression | Supported | Default Level | Library |
|---|---|---|---|
UNCOMPRESSED |
Y | N/A | N/A |
SNAPPY |
Y | N/A | klauspost/compress/snappy |
GZIP |
Y | 6 | klauspost/compress/gzip |
LZO |
N | N/A | N/A |
BROTLI |
Y | 6 | andybalholm/brotli |
LZ4 |
Y | Fast (0) | pierrec/lz4/v4 |
LZ4_RAW |
Y | 9 | pierrec/lz4/v4 |
ZSTD |
Y | 3 | klauspost/compress/zstd |
Compression notes:
- Standard writers default to
SNAPPY.NewArrowWriterdefaults toGZIP. - Set a file-level codec with
writer.WithCompressionCodec. - Set a per-column codec with a struct tag such as
parquet:"name=col, compression=GZIP". - Set codec-level compression levels with
writer.WithCompressionLevel(codec, level). All columns using that codec share the same level. LZ4uses the legacy framed LZ4 format.LZ4_RAWuses raw LZ4 blocks and is the preferred LZ4 variant in the Parquet specification.- Compression codecs enforce decompressed size limits, defaulting to 256 MB, via
compress.WithMaxDecompressedSize.
Writer types:
| Writer | Use |
|---|---|
ParquetWriter |
Write Go structs |
JSONWriter |
Convert JSON rows to Parquet |
CSVWriter |
Write flat CSV-like data |
ArrowWriter |
Write data using Arrow schemas |
Reader types:
| Reader | Use |
|---|---|
ParquetReader |
Read rows into Go structs or inferred schemas |
ColumnReader |
Read raw column values with repetition and definition levels |
For large files, read in chunks rather than loading all rows at once.
pw, err := writer.NewParquetWriter(fw, new(MyStruct),
writer.WithRowGroupSize(common.DefaultRowGroupSize), // default 128M
writer.WithPageSize(common.DefaultPageSize), // default 8K
)File sources implement separate reader and writer interfaces.
type ParquetFileReader interface {
io.Seeker
io.Reader
io.Closer
Open(name string) (ParquetFileReader, error)
Clone() (ParquetFileReader, error)
}
type ParquetFileWriter interface {
io.Writer
io.Closer
Create(name string) (ParquetFileWriter, error)
}Supported sources:
- Local filesystem
- HDFS
- S3 (AWS SDK v2)
- Google Cloud Storage
- Azure Blob Storage
- HTTP (read-only)
- Memory buffer
- GoCloud CDK generic blob storage
- OpenStack Swift
See source/README.md for source-specific details.
The Parquet format defines an optional CRC32 field in PageHeader. The checksum covers the compressed page data, not the page header itself.
Reader validation is controlled with reader.WithCRCMode.
| Scenario | Strict | Auto | Ignore (default) |
|---|---|---|---|
| CRC absent in header | Fail | Pass | Pass |
| CRC present and valid | Pass | Pass | Pass |
| CRC present and invalid | Fail | Fail | Pass |
Mode behavior:
common.CRCIgnoreskips validation and preserves backward-compatible behavior.common.CRCAutovalidates CRC when present and passes when absent.common.CRCStrictrequires CRC on every page and validates it.
Writer CRC computation is controlled with writer.WithWriteCRC.
pw, err := writer.NewParquetWriter(pFile, obj, writer.WithWriteCRC(true))CRC is computed for data pages, dictionary pages, and dictionary-encoded data pages.
The reader and writer support Apache Parquet modular encryption for encrypted footers (PARE) and plaintext footers signed with AES-GCM (PAR1). Page headers, data pages, dictionary pages, column metadata, column indexes, offset indexes, and bloom filter headers/bitsets are encrypted and decrypted when encryption metadata and the required keys are available.
Footer mode and column classification interact as follows:
| Footer mode | Plaintext column | Footer-key column | Column-key column |
|---|---|---|---|
Encrypted footer (PARE) |
Page/index/bloom modules are plaintext. The footer key is required to open the encrypted file metadata, regardless of column classification. | Page/index/bloom modules use the footer key; column metadata stays in the encrypted footer. | Page/index/bloom modules use the column key; encrypted column metadata is stored for readers with only the column key. |
Signed plaintext footer (PAR1) |
Page/index/bloom modules and column statistics are plaintext; readers without keys can read projected plaintext columns. | Page/index/bloom modules use the footer key; plaintext footer metadata is present but statistics are stripped. | Page/index/bloom modules use the column key; plaintext footer metadata is present but statistics are stripped. |
Writer column classification is selected with writer.WithColumnEncrypted(path, opts...), where path is the rootless leaf path in the file schema (without the root element). Path components are separated by common.ParGoPathDelimiter (\x01); build the value with common.PathToStr — . is an ordinary character in a name, not a separator. The path is matched against external Parquet names (the name= value in the struct tag); Go struct field names are not accepted, so the writer and reader.WithColumnKey apply the same path-resolution rules. Once the writer has a schema, it prepends the external schema root internally for validation and lookup. Root names are not stripped from option values: common.PathToStr([]string{"parquet_go_root", "ssn"}) will not match a rootless ssn column, but it can match a nested column whose first path component is actually named parquet_go_root.
// Omitted path: column is plaintext. Only the footer is encrypted.
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
)// Footer-key column; sibling unkeyed columns remain plaintext.
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("name", writer.ColumnFooterKey()),
)// Literal column key.
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("ssn", writer.ColumnKey(ssnKey)),
)// Literal column key plus stored key metadata for downstream KMS readers.
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("ssn", writer.ColumnKey(ssnKey, []byte("kms://prod/ssn"))),
)// Writer resolves the column key from metadata through its KeyRetriever.
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("ssn", writer.ColumnKeyByMetadata([]byte("ssn-key"))),
writer.WithKeyRetriever(keyRetriever),
)For callers that build EncryptionConfig literally, ColumnKeys[p] = writer.EncryptionColumnKey{} is equivalent to WithColumnEncrypted(p) and produces ENCRYPTION_WITH_FOOTER_KEY. To retrieve by metadata, set non-empty KeyMetadata and configure KeyRetriever; to use the footer key, keep the zero value or use ColumnFooterKey().
ColumnKeys[p] state |
How to produce | Resolved behavior |
|---|---|---|
| not in map | omit WithColumnEncrypted(p, ...) |
plaintext |
{} |
WithColumnEncrypted(p) or WithColumnEncrypted(p, ColumnFooterKey()) |
footer-key, no KeyMetadata stored |
{Key: bytes} |
WithColumnEncrypted(p, ColumnKey(key)) |
column-key, no KeyMetadata stored |
{Key: bytes, KeyMetadata: md} |
WithColumnEncrypted(p, ColumnKey(key, md)) |
column-key plus KeyMetadata stored in file |
{Key: nil, KeyMetadata: md} plus writer KeyRetriever |
WithColumnEncrypted(p, ColumnKeyByMetadata(md)) |
retriever called at write time; empty result is an error |
{Key: nil, KeyMetadata: md} with no writer KeyRetriever |
same call without retriever | construction error |
Repeated column options follow standard Go map semantics: the last call wins and no conflict detection runs. Applications that compose options dynamically should keep a single owner for each column path.
writer.WithColumnEncrypted("ssn", writer.ColumnKey(oldKey))
writer.WithColumnEncrypted("ssn", writer.ColumnFooterKey()) // final stateReader key options, including reader.WithColumnKey, supply key bytes directly. The writer API uses the structured WithColumnEncrypted to express column treatment — key metadata, the ColumnKeyByMetadata retriever path, and explicit ColumnFooterKey selection — none of which have a reader-side analogue.
Encrypted footer with one column-key column and the rest plaintext:
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("ssn", writer.ColumnKey(ssnKey)),
)Signed plaintext footer with one column-key column and the rest plaintext:
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithPlaintextFooter(true),
writer.WithColumnEncrypted("ssn", writer.ColumnKey(ssnKey)),
)Encrypted footer with a footer-key column and plaintext siblings:
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("name"),
)WithColumnEncrypted(p, ColumnFooterKey()) is the explicit selector that keeps p encrypted with the footer key while sibling columns omitted from ColumnKeys are plaintext.
Three-way mix in one file:
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("name"),
writer.WithColumnEncrypted("ssn", writer.ColumnKey(ssnKey)),
)All columns plaintext with an encrypted footer:
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
)KMS pattern where the writer already has the key:
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKey(footerKey),
writer.WithColumnEncrypted("ssn", writer.ColumnKey(ssnKey, []byte("ssn-key-id"))),
)Pure retriever pattern:
keyRetriever := func(keyMetadata []byte) ([]byte, error) {
return lookupKey(keyMetadata)
}
pw, err := writer.NewParquetWriter(fw, new(Student),
writer.WithFooterKeyMetadata([]byte("footer-key-id")),
writer.WithColumnEncrypted("ssn", writer.ColumnKeyByMetadata([]byte("ssn-key-id"))),
writer.WithKeyRetriever(keyRetriever),
)WithAADPrefix supplies the file AAD prefix. If WithSupplyAADPrefix(true) is set, readers must pass the same value with reader.WithAADPrefix. EncryptionAESGCMV1 encrypts all modules with AES-GCM; EncryptionAESGCMCTRV1 uses AES-CTR for page bodies and AES-GCM for metadata modules.
Security guidance:
- Plaintext columns expose values, statistics, indexes, and bloom filters in the clear. Use
ColumnKey(...)orColumnFooterKey()for sensitive fields. - Encrypted columns under plaintext-footer mode have
Statistics,SizeStatistics, andGeospatialStatisticsstripped from the plaintextColumnMetaDataand stored only in authenticatedEncryptedColumnMetadata. - Plaintext-footer encrypted columns still expose page counts, encodings, value counts, offsets, compressed sizes, key metadata, and column names through the plaintext footer. Use encrypted footer mode when those metadata are sensitive.
- Each file should use a unique
(AADPrefix, AADFileUnique)pair. Reusing the same pair with the same key weakens module-swap protection. AES_GCM_CTR_V1does not authenticate page bodies; useAES_GCM_V1when page-data tamper detection is required.
Reader behavior is driven by the file's per-column CryptoMetadata: nil means plaintext, ENCRYPTION_WITH_FOOTER_KEY means footer-key column, and ENCRYPTION_WITH_COLUMN_KEY means column-key column. reader.WithColumnKey(path, key) supplies a direct key for a rootless leaf path in the file schema, matched against the file's PathInSchema (external Parquet names); WithCaseInsensitive(true) accepts case-only differences, but Go struct field names with different spelling are not accepted. reader.WithKeyRetriever resolves keys from stored key_metadata. Once the reader has a schema, it prepends the external schema root internally for validation and lookup. Like writer column options, reader column-key paths must omit the schema root; a root name in the option value is treated as an ordinary path component. If a writer intentionally stores ENCRYPTION_WITH_COLUMN_KEY while using bytes equal to the footer key, downstream readers can decrypt it either with reader.WithColumnKey(path, footerKey) or with a retriever that returns footerKey for that column metadata.
Writer metadata-based keys are strict: ColumnKeyByMetadata(md) requires the writer's KeyRetriever to return a non-empty AES key at construction time. The reader API still treats missing column-key material as a read-time decryption failure because reader.WithColumnKey carries only key bytes, not expected key metadata.
Compatibility: apache/parquet-testing includes mixed plaintext/encrypted plaintext-footer fixtures generated through Parquet C++/parquet-mr test paths, and this repository reads them in interop tests. It does not currently include parquet-cpp 1.x mixed writer fixtures, so compatibility with older readers on writer-produced mixed files is based on Parquet spec compliance rather than direct fixture coverage. Files produced by this library should interoperate with spec-compliant readers when the same keys and AAD configuration are used.
Spec references:
- Modular encryption: https://parquet.apache.org/docs/file-format/data-pages/encryption/
- Bloom filter encryption: https://parquet.apache.org/docs/file-format/bloomfilter/
parquet-go supports Apache Parquet geospatial logical types and configurable JSON output through marshal.ConvertToJSONFriendly.
Overview:
GEOMETRYstores planar coordinates with optional CRS.GEOGRAPHYstores spherical coordinates with optional CRS and edge interpolation algorithm.- Physical storage is WKB in
BYTE_ARRAYfields. - CRS defaults to
OGC:CRS84when not provided. - GEOGRAPHY algorithms include
SPHERICAL,VINCENTY,THOMAS,ANDOYER, andKARNEY.
JSON output modes:
| Mode | Output |
|---|---|
| Hex | WKB data as hexadecimal strings |
| Base64 | WKB data as base64 strings |
| GeoJSON | RFC 7946 compliant GeoJSON output |
| Hybrid | GeoJSON plus raw WKB |
Defaults are GeoJSON for GEOGRAPHY and hex for GEOMETRY.
cfg := types.NewGeospatialConfig(
types.WithGeographyJSONMode(types.GeospatialModeGeoJSON),
types.WithGeometryJSONMode(types.GeospatialModeHex),
types.WithGeospatialHybridRawBase64(true),
types.WithGeospatialGeoJSONAsFeature(false),
types.WithGeospatialCoordinatePrecision(6),
types.WithGeospatialReprojector(func(crs string, gj map[string]any) (map[string]any, bool) {
return nil, false
}),
)
result := types.ConvertGeographyLogicalValue(wkbBytes, geogType, cfg)Supported WKB geometry types in the built-in converter:
- Point (2D)
- LineString (2D)
- Polygon (2D)
Other WKB types fall back to raw WKB. If WKB parsing fails, the converter also falls back to raw WKB with CRS or algorithm metadata when applicable.
Use WithNP(n) to set the number of parallel goroutines. The default is 4.
func NewParquetReader(pFile source.ParquetFileReader, obj any, opts ...ReaderOption) (*ParquetReader, error)
func NewParquetWriter(pFile source.ParquetFileWriter, obj any, opts ...WriterOption) (*ParquetWriter, error)
func NewJSONWriter(jsonSchema string, pfile source.ParquetFileWriter, opts ...WriterOption) (*JSONWriter, error)
func NewCSVWriter(md []string, pfile source.ParquetFileWriter, opts ...WriterOption) (*CSVWriter, error)
func NewArrowWriter(arrowSchema *arrow.Schema, pfile source.ParquetFileWriter, opts ...WriterOption) (*ArrowWriter, error)Build examples with the example build tag.
go build -tags example ./example/local_flat
go build -tags example ./example/local_nested
go build -tags example ./example/json_write
go build -tags example ./example/csv_write
go build -tags example ./example/new_logical
go build -tags example ./example/geospatial
go build -tags example ./example/bloom_filter
go build -tags example ./example/encrypt_write
go build -tags example ./example/all_types| Example | Description |
|---|---|
| local_flat | Write/read flat parquet file |
| local_nested | Write/read nested structures |
| read_partial | Read partial fields |
| read_partial2 | Read sub-structs |
| read_without_schema_predefined | Read without predefined schema |
| read_partial_without_schema_predefined | Read partial without predefined schema |
| json_schema | Define schema with JSON |
| json_write | Convert JSON to Parquet |
| convert_to_json | Convert Parquet to JSON |
| csv_write | CSV writer |
| csv_to_parquet | CSV file to Parquet |
| column_read | Read raw column data |
| type | Type examples |
| type_alias | Type alias examples |
| new_logical | New logical types including FLOAT16 and INTEGER |
| unknown_type | UNKNOWN logical type (always-null columns) |
| geospatial | GEOMETRY and GEOGRAPHY examples |
| bloom_filter | Bloom filter |
| encrypt_write | Write and read back encrypted Parquet files |
| encrypt_read | Read encrypted Parquet file |
| encrypt_read_aad | Read encrypted Parquet file with external AAD prefix |
| encrypt_read_plaintext_footer | Read encrypted Parquet file with plaintext footer |
| encrypt_read_uniform | Read uniformly encrypted Parquet file |
| datapagev2 | Data Page V2 |
| date | Date type |
| all_types | Comprehensive type support |
| arrow_to_parquet | Arrow schema to Parquet |
| variant-fine-control | VARIANT type fine control |
| dot_in_name | Dot in field name |
| keyvalue_metadata | Key-value metadata |
| writer | ParquetWriter from io.Writer |
| writer_file | WriterFile example |
| mem | In-memory file system |
- v1 README: original v1 documentation.
- v2 README: v2 documentation.
- source/README.md: file source implementations.
Contributions are welcome. Please submit issues or pull requests.
Apache License 2.0