|
| 1 | +# Consolidated metadata |
| 2 | + |
| 3 | +Consolidated metadata is a copy of every metadata document below a group, |
| 4 | +kept in one place. A reader can then open a whole hierarchy with one read. |
| 5 | + |
| 6 | +Consolidated metadata is a convention of zarr-python, the reference |
| 7 | +implementation. Neither Zarr specification defines it in full. This page |
| 8 | +first says what is settled, then describes the API. |
| 9 | + |
| 10 | +## Status in the specifications |
| 11 | + |
| 12 | +**Zarr v2.** The v2 spec has no consolidated metadata. |
| 13 | + |
| 14 | +- The `.zmetadata` file was designed in zarr-python |
| 15 | + [PR 268](https://github.com/zarr-developers/zarr-python/pull/268). It |
| 16 | + merged in November 2018 and shipped in zarr-python 2.3.0. |
| 17 | +- The |
| 18 | + [zarr-python 2 tutorial](https://zarr.readthedocs.io/en/v2.18.3/tutorial.html#consolidating-metadata) |
| 19 | + describes it. |
| 20 | +- zarr-specs [issue 113](https://github.com/zarr-developers/zarr-specs/issues/113), |
| 21 | + on standardizing the format, is open. |
| 22 | + |
| 23 | +**Zarr v3.** The core spec names the member but does not define its |
| 24 | +entries. |
| 25 | + |
| 26 | +- zarr-specs [PR 309](https://github.com/zarr-developers/zarr-specs/pull/309) |
| 27 | + proposes the `consolidated_metadata` member, with the `kind: "inline"` |
| 28 | + envelope that zarr-python 3 writes. It follows |
| 29 | + [issue 136](https://github.com/zarr-developers/zarr-specs/issues/136). It |
| 30 | + has been open since August 2024 and is not merged. |
| 31 | +- [PR 373](https://github.com/zarr-developers/zarr-specs/pull/373) merged |
| 32 | + in July 2026. Since then, the core spec names the member "for historical |
| 33 | + reasons" and fixes its envelope |
| 34 | + ([spec text](https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v3/core/index.rst#L802-L816)). |
| 35 | + The envelope is an object with: |
| 36 | + - `must_understand: false`, |
| 37 | + - `kind: "inline"`, |
| 38 | + - a `metadata` object. |
| 39 | +- PR 373 closed |
| 40 | + [issue 371](https://github.com/zarr-developers/zarr-specs/issues/371). |
| 41 | + That issue found a problem with the v3.1.0 extension rules. Read |
| 42 | + strictly, they put every consolidated group zarr-python 3 had written out |
| 43 | + of spec, because the envelope has no `name`. |
| 44 | + |
| 45 | +This package reads the envelope the spec fixes. It reads the entries as |
| 46 | +zarr-python writes them. |
| 47 | + |
| 48 | +## Zarr v3 |
| 49 | + |
| 50 | +Consolidated metadata holds the hierarchy below its group, with the group |
| 51 | +as the root. |
| 52 | + |
| 53 | +- The document of the node at `/a/b` is stored under the key `a/b`. The |
| 54 | + [stored representation](https://zarr-specs.readthedocs.io/en/v3.1.0/v3/core/index.html#stored-representation) |
| 55 | + strips the leading `/` of a path. |
| 56 | +- The documents and the group must form a tree. Only groups have child |
| 57 | + nodes, and the parent of every node is present. |
| 58 | + `ZarrV3ConsolidatedMetadata` checks this when it reads the documents. |
| 59 | + |
| 60 | +`NodeName` and `NodePath`, in `zarr_metadata.v3`, are string types. They |
| 61 | +satisfy the spec's rules for |
| 62 | +[node names](https://zarr-specs.readthedocs.io/en/v3.1.0/v3/core/index.html#node-names) |
| 63 | +and paths. They are modeled on the zarrs types with the same names. These |
| 64 | +functions check a string against those rules: |
| 65 | + |
| 66 | +- `validate_node_name_v3`, `is_node_name_v3` and `parse_node_name_v3`, |
| 67 | +- the matching `node_path` functions. |
| 68 | + |
| 69 | +### Reading |
| 70 | + |
| 71 | +A group does not read the documents its `consolidated_metadata` lists. |
| 72 | +Consolidated metadata is a convention of the reference implementation, not |
| 73 | +core metadata. So the group checks the |
| 74 | +[envelope that the core spec fixes](https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v3/core/index.rst#L802-L816), |
| 75 | +then holds the member as written. `CORE_CONTEXT` holds |
| 76 | +`CONSOLIDATED_METADATA_EXTRA_FIELD`, the definition that reads this |
| 77 | +envelope. |
| 78 | + |
| 79 | +A reader can use the member as a source of child documents, in place of |
| 80 | +the store. There are two ways: |
| 81 | + |
| 82 | +- Read one document with `read_node_metadata_v3` when that node is opened. |
| 83 | +- Read all of them at once, with one of: |
| 84 | + - the group's `consolidated()`, |
| 85 | + - `ZarrV3ConsolidatedMetadata`, |
| 86 | + - `read_consolidated_metadata_v3`, which returns problems instead of |
| 87 | + raising them. |
| 88 | + |
| 89 | +Either way, a document with a problem fails only when it is read. |
| 90 | + |
| 91 | +Which context the documents are read in: |
| 92 | + |
| 93 | +- `consolidated()` uses the group's own context. |
| 94 | +- The other three take a `context`. Pass `context=group.context` to use the |
| 95 | + group's own context. With no `context`, they use |
| 96 | + `CORE_AND_EXTENSIONS_CONTEXT`. |
| 97 | + |
| 98 | +### Writing |
| 99 | + |
| 100 | +To write consolidated metadata: |
| 101 | + |
| 102 | +1. Build a `ZarrV3ConsolidatedMetadata`. |
| 103 | +2. Pass it to the group's `update`. |
| 104 | + |
| 105 | +The group reads the listed models in its own context. It refuses a model |
| 106 | +that its context reads differently. Then it writes the document. |
| 107 | + |
| 108 | +`ZarrV3ConsolidatedMetadata` reads every document strictly. It also |
| 109 | +accepts node models as entries. It accepts such an entry when the entry's |
| 110 | +claims refine into the model's context. Otherwise it refuses the entry at |
| 111 | +its path. To consolidate children read in several contexts, consolidate |
| 112 | +them in the `union` of those contexts. |
| 113 | + |
| 114 | +## Zarr v2 |
| 115 | + |
| 116 | +A v2 hierarchy's consolidated metadata is the `.zmetadata` document at the |
| 117 | +root of the store. zarr-python 2.3 and later write it. It is an object |
| 118 | +with: |
| 119 | + |
| 120 | +- `zarr_consolidated_format: 1`, |
| 121 | +- a `metadata` object. This maps each metadata file's path to that file's |
| 122 | + contents, under keys such as `a/.zarray`, `a/.zattrs` and `a/b/.zgroup`. |
| 123 | + |
| 124 | +The format comes from zarr-python |
| 125 | +[PR 268](https://github.com/zarr-developers/zarr-python/pull/268). No |
| 126 | +specification defines it. |
| 127 | + |
| 128 | +`ZarrV2ConsolidatedMetadata` reads such a document. |
| 129 | +`read_consolidated_metadata_v2` does the same, but returns problems instead |
| 130 | +of raising them. Both take a `context`. The default is `CORE_V2_CONTEXT`. |
| 131 | + |
| 132 | +How the entries are read: |
| 133 | + |
| 134 | +- Each `.zarray` or `.zgroup` entry is read as a node, merged with its |
| 135 | + sibling `.zattrs`. |
| 136 | +- A `.zattrs` with no sibling is kept, but forms no node. |
| 137 | +- Any other entry must be JSON, and is kept. |
| 138 | + |
| 139 | +`to_json` returns the entries keyed by file, as written. |
| 140 | + |
| 141 | +The `.zmetadata` that zarr-python 3 writes for a v2 hierarchy has a known |
| 142 | +bug. `read_repaired_consolidated_metadata_v2` undoes it. See |
| 143 | +[Repairing known writer bugs](repair.md). |
0 commit comments