Persistent Rules¶
always_delete and always_update encode cleanup rules into the bundle itself. Once defined, they fire automatically on every future attach or fetch — whoever runs the pipeline, whatever tool they use.
always_delete¶
Remove rows that should never be in the bundle, regardless of what the source sends:
Now every future attach cleans automatically — no need to remember to add the filter:
always_update¶
Normalize or transform column values on every incoming record:
bundle.always_update("SET currency = UPPER(currency) WHERE currency IS NOT NULL")
bundle.always_update("SET region = 'EMEA' WHERE region IN ('Europe', 'EU', 'europe')")
bundle.always_update("SET amount = ROUND(amount, 2) WHERE amount IS NOT NULL")
bundle.always_update("SET event_type = LOWER(event_type) WHERE event_type IS NOT NULL")
bundle.commit("Added normalization rules")
ALWAYS UPDATE bundle SET currency = UPPER(currency) WHERE currency IS NOT NULL;
ALWAYS UPDATE bundle SET region = 'EMEA' WHERE region IN ('Europe', 'EU', 'europe');
ALWAYS UPDATE bundle SET amount = ROUND(amount, 2) WHERE amount IS NOT NULL;
ALWAYS UPDATE bundle SET event_type = LOWER(event_type) WHERE event_type IS NOT NULL;
COMMIT 'Added normalization rules';
Combining delete and update rules¶
Rules are applied in definition order — deletes first, then updates:
import bundlebase.sync as bb
bundle = bb.create("s3://analytics/events")
# Remove records that should never be ingested
bundle.always_delete("event_type = 'internal_test'")
bundle.always_delete("user_id IS NULL")
# Normalize what remains
bundle.always_update("SET event_type = LOWER(event_type) WHERE event_type IS NOT NULL")
bundle.always_update("SET region = UPPER(region) WHERE region IS NOT NULL")
bundle.always_update("SET currency = UPPER(currency) WHERE currency IS NOT NULL")
bundle.commit("Initial setup with cleanup rules")
ALWAYS DELETE FROM bundle WHERE event_type = 'internal_test';
ALWAYS DELETE FROM bundle WHERE user_id IS NULL;
ALWAYS UPDATE bundle SET event_type = LOWER(event_type) WHERE event_type IS NOT NULL;
ALWAYS UPDATE bundle SET region = UPPER(region) WHERE region IS NOT NULL;
ALWAYS UPDATE bundle SET currency = UPPER(currency) WHERE currency IS NOT NULL;
COMMIT 'Initial setup with cleanup rules';
Viewing defined rules¶
Why this matters¶
Without persistent rules, every engineer who runs the pipeline has to remember to apply the same filters. When someone forgets — or writes a new pipeline from scratch — dirty data gets in. Persistent rules make the cleanup part of the bundle definition, not the pipeline script.