Skip to content

metadata

zarr.metadata

zarr.metadata.migrate_v3

migrate_to_v3

migrate_to_v3(
    zarr_v2: AnyArray | Group,
    output_path: StorePath,
    dry_run: bool = False,
) -> None

Migrate all v2 metadata in a Zarr array/group to v3.

Note - if a group is provided, then all arrays / groups within this group will also be converted. A zarr.json file will be created for each level and written to output_path, with any v2 files (.zarray, .zattrs etc.) left as-is.

Parameters:

  • zarr_v2 (Array | Group) –

    An array or group with zarr_format = 2

  • output_path (StorePath) –

    The store path to write generated v3 metadata to.

  • dry_run (bool, default: False ) –

    Enable a 'dry run' - files that would be created are logged, but no files are created or changed.

Source code in zarr/metadata/migrate_v3.py
def migrate_to_v3(zarr_v2: AnyArray | Group, output_path: StorePath, dry_run: bool = False) -> None:
    """Migrate all v2 metadata in a Zarr array/group to v3.

    Note - if a group is provided, then all arrays / groups within this group will also be converted.
    A zarr.json file will be created for each level and written to output_path, with any v2 files
    (.zarray, .zattrs etc.) left as-is.

    Parameters
    ----------
    zarr_v2 : Array | Group
        An array or group with zarr_format = 2
    output_path : StorePath
        The store path to write generated v3 metadata to.
    dry_run : bool, optional
        Enable a 'dry run' - files that would be created are logged, but no files are created or changed.
    """
    if not zarr_v2.metadata.zarr_format == 2:
        raise TypeError("Only arrays / groups with zarr v2 metadata can be converted")

    if isinstance(zarr_v2.metadata, GroupMetadata):
        _convert_group(zarr_v2, output_path, dry_run)
    else:
        _convert_array(zarr_v2, output_path, dry_run)

migrate_v2_to_v3

migrate_v2_to_v3(
    *,
    input_store: Store,
    output_store: Store | None = None,
    dry_run: bool = False,
) -> None

Migrate all v2 metadata in a Zarr store to v3.

This will create a zarr.json file at each level of a Zarr hierarchy (for every group / array). v2 files (.zarray, .zattrs etc.) will be left as-is.

Parameters:

  • input_store (Store) –

    Input Zarr to migrate.

  • output_store (Store, default: None ) –

    Output location to write v3 metadata (no array data will be copied). If not provided, v3 metadata will be written to input_store.

  • dry_run (bool, default: False ) –

    Enable a 'dry run' - files that would be created are logged, but no files are created or changed.

Source code in zarr/metadata/migrate_v3.py
def migrate_v2_to_v3(
    *,
    input_store: Store,
    output_store: Store | None = None,
    dry_run: bool = False,
) -> None:
    """Migrate all v2 metadata in a Zarr store to v3.

    This will create a zarr.json file at each level of a Zarr hierarchy (for every group / array).
    v2 files (.zarray, .zattrs etc.) will be left as-is.

    Parameters
    ----------
    input_store : Store
        Input Zarr to migrate.
    output_store : Store, optional
        Output location to write v3 metadata (no array data will be copied). If not provided, v3 metadata will be
        written to input_store.
    dry_run : bool, optional
        Enable a 'dry run' - files that would be created are logged, but no files are created or changed.
    """

    zarr_v2 = zarr.open(store=input_store, mode="r+")

    if output_store is not None:
        # w- access to not allow overwrite of existing data
        output_path = sync(StorePath.open(output_store, path="", mode="w-"))
    else:
        output_path = zarr_v2.store_path

    migrate_to_v3(zarr_v2, output_path, dry_run=dry_run)

remove_metadata async

remove_metadata(
    store: Store,
    zarr_format: ZarrFormat,
    force: bool = False,
    dry_run: bool = False,
) -> None

Remove all v2 (.zarray, .zattrs, .zgroup, .zmetadata) or v3 (zarr.json) metadata files from the given Zarr.

Note - this will remove metadata files at all levels of the hierarchy (every group and array).

Parameters:

  • store (Store) –

    Zarr to remove metadata from.

  • zarr_format (ZarrFormat) –

    Which format's metadata to remove - 2 or 3.

  • force (bool, default: False ) –

    When False, metadata can only be removed if a valid alternative exists e.g. deletion of v2 metadata will only be allowed when v3 metadata is also present. When True, metadata can be removed when there is no alternative.

  • dry_run (bool, default: False ) –

    Enable a 'dry run' - files that would be deleted are logged, but no files are removed or changed.

Source code in zarr/metadata/migrate_v3.py
async def remove_metadata(
    store: Store,
    zarr_format: ZarrFormat,
    force: bool = False,
    dry_run: bool = False,
) -> None:
    """Remove all v2 (.zarray, .zattrs, .zgroup, .zmetadata) or v3 (zarr.json) metadata files from the given Zarr.

    Note - this will remove metadata files at all levels of the hierarchy (every group and array).

    Parameters
    ----------
    store : Store
        Zarr to remove metadata from.
    zarr_format : ZarrFormat
        Which format's metadata to remove - 2 or 3.
    force : bool, optional
        When False, metadata can only be removed if a valid alternative exists e.g. deletion of v2 metadata will
        only be allowed when v3 metadata is also present. When True, metadata can be removed when there is no
        alternative.
    dry_run : bool, optional
        Enable a 'dry run' - files that would be deleted are logged, but no files are removed or changed.
    """

    if not store.supports_deletes:
        raise ValueError("Store must support deletes to remove metadata")
    store_path = await StorePath.open(store, path="", mode="r+")

    metadata_files_all = {
        2: [ZARRAY_JSON, ZATTRS_JSON, ZGROUP_JSON, ZMETADATA_V2_JSON],
        3: [ZARR_JSON],
    }

    if zarr_format == 2:
        alternative_metadata = 3
    else:
        alternative_metadata = 2

    awaitables = []
    async for file_path in store.list():
        parent_path, _, file_name = file_path.rpartition("/")

        if file_name not in metadata_files_all[zarr_format]:
            continue

        if force or await _metadata_exists(
            cast(ZarrFormat, alternative_metadata), store_path / parent_path
        ):
            _logger.info("Deleting metadata at %s", store_path / file_path)
            if not dry_run:
                awaitables.append((store_path / file_path).delete())
        else:
            raise ValueError(
                f"Cannot remove v{zarr_format} metadata at {store_path / file_path} - no v{alternative_metadata} "
                "metadata exists. To delete anyway, use the 'force' option."
            )

    await asyncio.gather(*awaitables)