Recipe: Handle Schema and Type Drift
Freeze inferred schemas, count type mismatches, and decide when to coerce or fail.
If you do not provide a schema, BlazeRules infers rule-referenced field types from the first evaluated batch. After that, the engine treats the schema as fixed.
Example:
{"account_age_days": 42}If a later record sends:
{"account_age_days": "forty-two"}the value is a type mismatch. The configured type_mismatch_mode decides what happens:
| Mode | Behavior |
|---|---|
NULL_ON_TYPE_ERROR | Treat the field as null for that row; normal comparisons return false. |
COERCE | Try lightweight coercion such as "42" to an integer. |
HARD_FAIL_TYPE | Throw a structured type error for the batch. |
Production default:
cfg = blazerules.EngineConfig()
cfg.ingest_error_mode = blazerules.IngestErrorMode.SKIP_AND_COUNT
cfg.type_mismatch_mode = blazerules.TypeMismatchMode.NULL_ON_TYPE_ERRORCLI equivalent: run the same policy in a shell script
cat events.ndjson | blazerules eval --rules rules.yaml --input ndjson --stdin --output summaryThe defaults (SKIP_AND_COUNT / NULL_ON_TYPE_ERROR) apply unless you pass --type-mismatch-mode / --ingest-error-mode for non-default policies.
Watch:
result = engine.evaluate_ndjson(payload)
print(result.error_counts)
print(result.error_samples)CLI equivalent: print drift diagnostics from stdin
cat events.ndjson | blazerules eval --rules rules.yaml --input ndjson --stdin --output summaryThe summary reports processed/skipped/error counters.
For important fields, pin the type in fields: so inference cannot guess differently across environments:
fields:
account_age_days: {type: int32, nullable: false}
amount: {type: float32, nullable: false}
event_ts_ms: {type: timestamp_ms, nullable: false}Updated 9 days ago
Did this page help you?