Skip to main content

dagster-delta

Dagster deltalake implementation for Pyarrow & Polars. Originally forked from dagster-deltalake with customizations.

The IO Managers support partition mapping, custom write modes, special metadata configuration for advanced use cases.

The supported write modes:

  • error
  • append
  • overwrite
  • ignore
  • merge
  • create_or_replace

Merge

dagster-delta supports MERGE execution with a couple pre-defined MERGE types (dagster_delta.config.MergeType):

  • deduplicate_insert <- Deduplicates on write
  • update_only <- updates only the matches records
  • upsert <- updates existing matches and inserts non matched records
  • replace_and_delete_unmatched <- updates existing matches and deletes unmatched
  • custom <- custom Merge with MergeOperationsConfig

Example:

from dagster_delta import DeltaLakePolarsIOManager, WriteMode, MergeConfig, MergeType
from dagster_delta_polars import DeltaLakePolarsIOManager


@asset(
    key_prefix=["my_schema"]  # will be used as the schema (parent folder) in Delta Lake
)
def my_table() -> pl.DataFrame:  # the name of the asset will be the table name
    ...


defs = Definitions(
    assets=[my_table],
    resources={
        "io_manager": DeltaLakePolarsIOManager(
            root_uri="s3://bucket",
            mode=WriteMode.merge,  # or just "merge"
            merge_config=MergeConfig(
                merge_type=MergeType.upsert,
                predicate="s.a = t.a",
                source_alias="s",
                target_alias="t",
            ),
        )
    },
)

Custom merge (gives full control)

from dagster_delta import (
    DeltaLakePolarsIOManager,
    WriteMode,
    MergeConfig,
    MergeType,
    MergeOperationsConfig,
)
from dagster_delta_polars import DeltaLakePolarsIOManager


@asset(
    key_prefix=["my_schema"]  # will be used as the schema (parent folder) in Delta Lake
)
def my_table() -> pl.DataFrame:  # the name of the asset will be the table name
    ...


defs = Definitions(
    assets=[my_table],
    resources={
        "io_manager": DeltaLakePolarsIOManager(
            root_uri="s3://bucket",
            mode=WriteMode.merge,  # or just "merge"
            merge_config=MergeConfig(
                merge_type=MergeType.custom,
                predicate="s.a = t.a",
                source_alias="s",
                target_alias="t",
                merge_operations_config=MergeOperationsConfig(
                    when_not_matched_insert_all=[
                        WhenNotMatchedInsertAll(predicate="s.price > 600")
                    ],
                    when_matched_update_all=[WhenMatchedUpdateAll()],
                ),
            ),
        )
    },
)

Special metadata configurations

Add additional table_configuration

Specify additional table configurations for configuration in write_deltalake.

@dg.asset(
    io_manager_key="deltalake_io_manager",
    metadata={"table_configuration": {"delta.enableChangeDataFeed": "true"}},
)
def my_asset() -> pl.DataFrame: ...

Overwrite the write mode

Override the write mode to be used in write_deltalake.

@dg.asset(
    io_manager_key="deltalake_io_manager",
    metadata={"mode": "append"},
)
def my_asset() -> pl.DataFrame: ...

Overwrite the custom_metadata

Override the custom_metadata to be used in write_deltalake.

@dg.asset(
    io_manager_key="deltalake_io_manager",
    metadata={"custom_metadata": {"owner": "John Doe"}},
)
def my_asset() -> pl.DataFrame: ...

Overwrite the write schema_mode

Override the schema_mode to be used in write_deltalake.

@dg.asset(
    io_manager_key="deltalake_io_manager",
    metadata={"schema_mode": "merge"},
)
def my_asset() -> pl.DataFrame: ...

Overwrite the writer_properties

Override the writer_properties to be used in write_deltalake.

@dg.asset(
    io_manager_key="deltalake_io_manager",
    metadata={
        "writer_properties": {
            "compression": "SNAPPY",
        }
    },
)
def my_asset() -> pl.DataFrame: ...

Overwrite the merge_predicate

Override the merge_predicate to be used with merge execution.

@dg.asset(
    io_manager_key="deltalake_io_manager",
    metadata={"merge_predicate": "s.foo = t.foo AND s.bar = t.bar"},
)
def my_asset() -> pl.DataFrame: ...

Overwrite the schema

Override the schema of where the table will be saved

@dg.asset(
    io_manager_key="deltalake_io_manager",
    metadata={"schema": "custom_db_schema"},
)
def my_asset() -> pl.DataFrame: ...

Set the columns that need to be read

Override the columns to only load these columns in

@dg.asset(
    io_manager_key="deltalake_io_manager",
    ins={"upstream_asset": dg.AssetIn(metadata={"columns": ["foo", "bar"]})},
)
def my_asset(upstream_asset) -> pl.DataFrame: ...

Override table name using root_name

Instead of using the asset_name for the table name it's possible to set a custom table name using the root_name in the asset defintion metadata.

This is useful where you have two or multiple assets who have the same table structure, but each asset is a subset of the full table partition_definition, and it wasn't possible to combine this into a single asset due to requiring different underlying Op logic and/or upstream assets:

import polars as pl
import dagster as dg


@dg.asset(
    io_manager_key="deltalake_io_manager",
    partitions_def=dg.StaticPartitionsDefinition(["a", "b"]),
    metadata={
        "partition_expr": "foo",
        "root_name": "asset_partitioned",
    },
)
def asset_partitioned_1(upstream_1: pl.DataFrame, upstream_2: pl.DataFrame) -> pl.DataFrame: ...


@dg.asset(
    partitions_def=dg.StaticPartitionsDefinition(["c", "d"]),
    metadata={
        "partition_expr": "foo",
        "root_name": "asset_partitioned",
    },
)
def asset_partitioned_2(upstream_3: pl.DataFrame, upstream_4: pl.DataFrame) -> pl.DataFrame: ...

Effectively this would be the flow:


                 {static_partition_def: [a,b]}
┌───────────┐
│upstream 1 ├─┐ ┌────────────────────────┐
└───────────┘ │ │                        │            write to storage on partition (a,b)
┌───────────┐ └─►   asset_partitioned_1  ├──────────────────────┐
│upstream 2 ├───►                        │                      │
└───────────┘   └────────────────────────┘       ┌──────────────▼──────────────────┐
                                                 │                     partitions  │
                                                 │  asset_partitioned:             │
                                                 │                     [a,b,c,d]   │
┌───────────┐   ┌────────────────────────┐       └──────────────▲──────────────────┘
│upstream 3 ├──┐│                        │                      │
└───────────┘  └►   asset_partitioned_2  │                      │
┌───────────┐ ┌─►                        ├──────────────────────┘
│upstream 4 ├─┘ └────────────────────────┘            write to storage on partition (c,d)
└───────────┘
                 {static_partition_def: [c,d]}

Metadata

Release files for dagster-delta 0.5.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dagster-delta 0.5.9
File Size Uploaded Provenance
dagster_delta-0.5.9.tar.gz 128.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dagster-delta 0.5.9
File Interpreter ABI Platform
dagster_delta-0.5.9-py3-none-any.whl Python 3 none any Details

Total release size: 160.1 kB

Release files / dagster_delta-0.5.9.tar.gz

Download URL dagster_delta-0.5.9.tar.gz
Size 128.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0ce5b35472bb47b9672237c9b7544f8a89a2ae75b973eae79405f57503a1f7f0
BLAKE2b-256 checksum
How to use checksums
cad5ae6022a0215be0e3c696ea60d224d07cccbba4e1f9b1de3119fdee2a58d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / dagster_delta-0.5.9-py3-none-any.whl

Download URL dagster_delta-0.5.9-py3-none-any.whl
Size 31.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47f2daa6cb4223edb9ba0dd9e404613cefc81a9ca4d70ee17014bed3f8bcce14
BLAKE2b-256 checksum
How to use checksums
22b4d6c00435151ff602764b9c1fde3e338d463e5680d52123b548ece0786880
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for dagster-delta 0.5.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page