Migration: 0.14 → 0.15¶
ETLantic 0.15 ships three themes:
- Safe SQL Lowering — portable kernel +
portable-relational/1→ typed SQL IR (PostgreSQL reference viaetlantic-sql) - Extract / Load / asset — public authoring vocabulary rename
- LocalScheduler — direct-execution boundary for
Pipeline.run/arun
Prefer the new authoring names immediately; legacy Source / Sink /
binding= emit DeprecationWarning and are removed in 0.16.
Safe SQL Lowering¶
Install etlantic-sql==0.15.0. Portable plans that fit the claimed SQL
compiler surface no longer require a native @implementation("sql") under
portable_transform_policy="require". Native SQL implementations remain
selectable. Trusted SQL fragments are rejected in portable definitions.
See SQL and the
portable compiler matrix.
LocalScheduler¶
Pipeline.run / arun enter through LocalScheduler. Observable report
shape and plan fingerprints are preserved. Airflow compilation is unchanged.
Optional Prefect packaging is 0.16 Gate B (ExecutionScheduler MVP).
Authoring vocabulary removal (Source / Sink / binding=) is the
independent 0.16 Gate A.
Mapping table¶
| 0.14 (legacy) | 0.15 (preferred) | Notes |
|---|---|---|
Source[T] |
Extract[T] |
Source subclasses Extract |
Sink[T] |
Load[T] |
Sink subclasses Load |
binding= on Source/Sink |
asset= on Extract/Load |
Reject specifying both |
.binding property |
.asset |
.binding warns |
Profile(bindings=...) |
Profile(assets=...) |
One internal store |
Profile JSON "bindings" |
Prefer "assets" (mirrored "bindings" in 0.15) |
Plans keep bindings-only snapshots |
RunRequest(binding_overrides=...) |
RunRequest(asset_overrides=...) |
Same map |
Before / after¶
# 0.14
from etlantic import Pipeline, Sink, Source
class CustomerPipeline(Pipeline):
raw: Source[RawCustomer] = Source(binding="customer_source")
curated: Sink[Customer] = Sink(input=normalized.result, binding="customer_sink")
profile = Profile(name="dev", bindings={"customer_source": "memory"})
# 0.15
from etlantic import Extract, Load, Pipeline
class CustomerPipeline(Pipeline):
raw: Extract[RawCustomer] = Extract(asset="customer_source")
curated: Load[Customer] = Load(input=normalized.result, asset="customer_sink")
profile = Profile(name="dev", assets={"customer_source": "memory"})
Unchanged semantics¶
- Logical graph topology and validation rules
- Plan fingerprints for equivalent pipelines/profiles (profile snapshots still
serialize the pre-0.15
bindingsshape without anassetskey) - Runtime read/write behavior and plugin dispatch
- DPCS round-trips and interface input/output roles
Retained protocol / wire names¶
Do not rename these for compatibility:
NodeKindvalues"source"/"sink"- Graph / plan field
bindingon nodes; plan mapbindings(BindingDescriptor) - DPCS extension field
etlantic:binding - Plugin APIs:
StorageBinding.read/write(binding=...), SQL/Spark*_from_binding - Port wiring:
Step.bindings,SubpipelineInstance.bindings SourceLocationdiagnostics; viz edge attributesource- SQL / SparkForge metadata fields named
source
0.16 deletion checklist¶
Remove after the 0.16 compatibility window:
-
Source/Sinkpublic classes and exports -
binding=constructor kwargs on Extract/Load - Public
.bindingproperty on Extract/Load -
Profile(bindings=...)authoring path and mirrored JSONbindingsemission (after consumers migrate toassets) -
RunRequest.binding_overridesauthoring path - Compatibility stubs in docs stubs (
SOURCES.md/SINKS.md) - Deprecation warning helpers dedicated to this rename