Schema composition
Schema inheritance reuses definitions. A derived schema can adjust field properties, copy field definitions, or remove constraints. Inheritance does not create nested input data; that is the role of child schemas.
Inherit field properties
from data_canon import as_dc_instance
from data_schemer.schema_projector import SchemaProjector
definitions = {
"base": {"variables": {
"iterations": {
"type": "Integer", "optional": True, "default": 20,
"help": "Maximum iteration count",
},
}},
"production": {
"inherit": ["base"],
"variables": {"iterations": {"default": 100}},
},
}
projector = SchemaProjector(definitions, schema_name="production")
projection = projector.get_projection(as_dc_instance({}))
assert projection.data == {"iterations": 100}
assert projector.schema_variables["iterations"]["type"] == "Integer"
The local default replaces the inherited default while type, optional,
and help remain inherited. Overrides merge field properties. Each property’s
value is replaced as a whole: a new choices list replaces the inherited list,
and a new Mapping default replaces the inherited Mapping default.
For inherit: ["first", "second"], the first base wins when both explicitly
define the same property. The second base fills properties absent from the
first. Local variables properties take precedence over every base. Implicit
defaults such as optional: False are added after composition.
Copy a field definition
definitions["production"]["copy_variables"] = {"report_limit": "base@iterations"}
definitions["production"]["variables"]["report_limit"] = {
"default": 5,
"help": "Maximum number of reported entries",
}
projector = SchemaProjector(definitions, schema_name="production")
assert projector.get_projection(as_dc_instance({})).data == {
"iterations": 100, "report_limit": 5,
}
copy_variables maps a destination name to "schema@field". The source field
uses its resolved definition, including inheritance. A copy replaces an
inherited destination definition, then local properties for the destination
override the copied properties.
Same-schema copies can refer to later copy entries. Cyclic copies and cyclic schema inheritance are rejected. Copies run before removals, so a same-schema source may be copied and then removed from the final schema.
Remove properties or fields
definitions["flexible"] = {
"inherit": ["base"],
"delete_properties": {"iterations": ["type", "default"]},
}
projector = SchemaProjector(definitions, schema_name="flexible")
assert projector.get_projection(as_dc_instance({})).data == {}
assert projector.get_projection(as_dc_instance({"iterations": "automatic"})).data == {
"iterations": "automatic",
}
The field remains optional, but its type constraint and default are removed.
Use delete_variables: ["iterations"] to remove the whole field definition.
Removing an absent field or property is an error, catching misspelled names.
Setting default to None supplies a Null DataCanon Instance (DCI) default. It does not remove a
default. Use delete_properties for removal.
Resolution order
For each schema, DataSchemer (DS) composes inherited field properties, applies local overrides and copies, then removes properties and fields. The copied destination always receives its local overrides after the copy. Implicit property defaults and final validation follow composition and removal.
The schema’s original definition dictionaries are not modified by field
resolution. A schema_variables property returns a copy of the compiled metadata.
update_variables has been removed. Put property overrides directly under
variables. An occurrence of update_variables, including an empty Mapping,
raises a migration error.
Other inherited metadata
child_schemas accumulates in base order, followed by locally declared names,
with duplicates removed. conflicts includes inherited groups.
print_attribute has its own merge rules for output configuration, including
extending lists of choices and exclusions. Those rules are separate from
ordinary field-property replacement; see the
behavioral reference.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.