Skip to main content

A convenience wrapper around PyIceberg for simplified data loading into Apache Iceberg tables

Project description

iceberg-loader

PyPI - Version PyPI - Python Version PyPI - Downloads Coverage CI License: MIT

📚 Documentation

A convenience wrapper around PyIceberg that simplifies data loading into Apache Iceberg tables. PyArrow-first, handles messy JSON, schema evolution, idempotent replace, upsert, batching, and streaming out of the box.

Status: Actively developed and under testing. PRs are welcome! Currently tested against Hive Metastore; REST Catalog support is planned.

Why iceberg-loader?

  • Messy JSON friendly: auto-serializes dict/list/mixed fields to strings so writes don't fail.
  • Schema evolution: add columns on the fly (opt-in), preserves field IDs.
  • Safe writes: append/overwrite, idempotent replace via replace_filter, upsert.
  • Stream friendly: commit intervals, batches, IPC streams.
  • Single config: LoaderConfig sets defaults; override per-call if needed.

Install

pip install "iceberg-loader[all]"

Or with uv:

uv add "iceberg-loader[all]"

Quickstart

from iceberg_loader import LoaderConfig, load_data_to_iceberg
from iceberg_loader.utils.arrow import create_arrow_table_from_data

catalog = load_catalog("default")
table_id = ("default", "comparison_complex_json")

data = [
    {"id": 1, "complex_field": {"a": 1, "b": "nested"}, "signup_date": "2023-01-01"},
    {"id": 2, "complex_field": {"a": 2, "b": "another", "c": [1, 2]}, "signup_date": "2023-01-02"},
    {"id": 3, "complex_field": [1, 2, 3], "signup_date": "2023-01-02"},
]

arrow_table = create_arrow_table_from_data(data)

config = LoaderConfig(write_mode="append", partition_col="day(signup_date)", schema_evolution=True)
load_data_to_iceberg(arrow_table, table_id, catalog, config=config)

Which function to use?

Function Use when... Input Format
load_data_to_iceberg You have a single pa.Table in memory. pyarrow.Table
load_batches_to_iceberg You have a generator/iterator of batches (memory efficient). Iterator of pyarrow.RecordBatch
load_ipc_stream_to_iceberg You are reading from an Arrow IPC stream file/socket. File-like object or path

Preparing Data

Use helpers to convert Python dictionaries to Arrow format (handling messy types automatically):

from iceberg_loader.utils.arrow import create_arrow_table_from_data, create_record_batches_from_dicts

# 1. Convert list of dicts -> pa.Table
arrow_table = create_arrow_table_from_data(data_list)

# 2. Convert iterator of dicts -> Iterator[pa.RecordBatch]
batches = create_record_batches_from_dicts(data_generator(), batch_size=10000)

Alternatively, use standard PyArrow conversion: pa.Table.from_pylist(data).

Public API & Stability

  • Public surface: LoaderConfig, load_data_to_iceberg, load_batches_to_iceberg, load_ipc_stream_to_iceberg.
  • Everything else is internal and may change without notice; always pass options via LoaderConfig.
  • Avoid legacy positional arguments—use the config parameter only.
  • LoaderConfig validates partition expressions and rejects unsafe combos (e.g., replace_filter with upsert, identity partition on _load_dttm).

How we version

  • Semantic Versioning starting at 0.1.x: MINOR for compatible features, PATCH for fixes, MAJOR for breaking API changes.
  • Breaking changes only happen on the public surface noted above.
  • Prefer partition transforms for timestamps (day(ts), hour(ts)), especially when using load_timestamp.

Release checklist

  • Bump version in pyproject.toml and src/iceberg_loader/__about__.py (they must match).
  • Update RELEASE.md with highlights and breaking notes.
  • Run uv lock --locked and commit uv.lock if it changes.
  • Run uv run ruff check ., uv run mypy src/iceberg_loader tests, and uv run python -m pytest.
  • Tag and push (git tag -a vX.Y.Z ...), then let CI publish.

Contributing

We welcome contributions! See CONTRIBUTING.md for setup, coding style, and PR guidelines.

hatch run lint
hatch run test

Contributors

Thanks to all contributors who have helped make this project better!

Made with contrib.rocks.

License

iceberg-loader is distributed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iceberg_loader-0.1.2.tar.gz (17.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

iceberg_loader-0.1.2-py3-none-any.whl (22.2 kB view details)

Uploaded Python 3

File details

Details for the file iceberg_loader-0.1.2.tar.gz.

File metadata

  • Download URL: iceberg_loader-0.1.2.tar.gz
  • Upload date:
  • Size: 17.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for iceberg_loader-0.1.2.tar.gz
Algorithm Hash digest
SHA256 7862d4cb42982bbbb8e307852ad4ad36674a6ebe5e92fb9dbe536b9635e10386
MD5 c325d18b4eea28d6794f5a52f98b22e1
BLAKE2b-256 1a81ab57e876869d78e2df5081a28e1e3fe9d77662be2f9b5a3af127ef889a57

See more details on using hashes here.

File details

Details for the file iceberg_loader-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: iceberg_loader-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 22.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for iceberg_loader-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 84ee59fc8b27bacb54f3a81fb8e8804e06927da04ad37d08e8f356cd9ac20628
MD5 1105e53d3b7ec69ee2dbdfa2714e8199
BLAKE2b-256 b64f7c705fc965e2eec9c1acd5d1a54a07061054a358cfadcf37d92127b81067

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page