Edit page in Livemark
(2026-10-15 21:45)

Data Package versions

This page documents how the framework resolves and handles the Data Package standard versions (v1 and v2).

Declaring a version

A descriptor declares its version through $schema, a JSON Schema profile URL:

package = Package({
    "$schema": "https://datapackage.org/profiles/2.0/datapackage.json",
    "name": "package",
    # ... v2 features are accepted from here on
})

The standard profiles are hosted at https://datapackage.org/profiles/{1.0,2.0}/{datapackage,dataresource,tableschema,tabledialect}.json.

Resolution rules

The version of a descriptor is resolved once, top-down, at descriptor-validation time. In accordance with the specification, only the root object is expected to have a $schema property; all child objects inherit the resolved version of the root.

The resolved version depends on the descriptor's own declaration:

Descriptor state Resolved version
Under a v1/v2/unknown ancestor the ancestor's version
$schema standard profile URL v1 or v2 (from the URL)
$schema custom URL unknown (superset)
$schema absent v1

Version gates

v2-specific features apply on explicit v2 version or when version is unknown. These features may raise errors or be ignored however when validating with unambiguous v1 version. See table below for examples of behavior changes.

Feature v1 v2 / unknown
name restricted to the v1 pattern enforced any string
missingValues object form {value, label?} rejected accepted
exclusiveMinimum / exclusiveMaximum rejected accepted

Detached children keep the inherited version

Resource and Schema store the version they resolved at import time (a private _datapackage_version). This stored version is threaded top-down at import, and seeded back into every detached validation, so that:

Exports stay canonical: by default, exporting the descriptor of children and reimporting them will change the behavior. The absent $schema property of the children is interpreted as v1 at re-import. Exporting with upgrade=True produces however a standalone descriptor of a child (see below).

Upgrading to v2

upgrade() returns a new instance (the original is untouched) whose descriptor tree is transformed into the v2 form — also available as an export option: to_descriptor(upgrade=True).

A $schema or profile pointing to a custom profile URL is kept as-is: an automatic upgrade of a custom profile is currently not supported. Its upgrade is up to its author. As a consequence, an upgraded custom profile resolves to "unknown" (permissive).

package = Package("package-v1.json")
v2_package = package.upgrade()  # a new, v2 instance