unity catalog

GuideUse Unity CatalogVolumes and files

Manage volumes

Create external and managed Unity Catalog volumes, inspect, rename, and delete them, and see what happens to their files.

A Unity Catalog volume governs a directory of files that aren't a table: CSV drops, documents, images, model inputs. Like a table, a volume lives in a schema and has a three-level name, such as retail.files.landing.

Volumes come in two types:

  • An external volume points at a directory you already have. Unity Catalog records the location and never deletes the files.
  • A managed volume gets a directory that Unity Catalog allocates under the schema's or catalog's storage root. Deleting the volume deletes that directory.

For how volumes fit into the namespace, see Core concepts.

Set up the client

Set up the client for your interface:

Start Python with the SDK:

uv run --with unitycatalog-client==0.7.0 python -m asyncio
volumes.pyFull script
from unitycatalog.client import (
    ApiClient,
    CatalogsApi,
    Configuration,
    CreateCatalog,
    CreateSchema,
    CreateVolumeRequestContent,
    SchemasApi,
    UpdateVolumeRequestContent,
    VolumesApi,
    VolumeType,
)

config = Configuration(host="http://localhost:8080/api/2.1/unity-catalog")

The examples use a catalog retail with a schema files whose storage root is $UC_DOCS_ROOT/managed:

volumes.pyFull script
await CatalogsApi(api).create_catalog(CreateCatalog(name="retail"))
await SchemasApi(api).create_schema(
    CreateSchema(
        name="files",
        catalog_name="retail",
        storage_root=f"file://{ROOT}/managed",
    )
)

Create an external volume

Point the volume at an existing directory. This example assumes $UC_DOCS_ROOT/landing holds a few files.

volumes.pyFull script
landing = await volumes.create_volume(
    CreateVolumeRequestContent(
        catalog_name="retail",
        schema_name="files",
        name="landing",
        volume_type=VolumeType.EXTERNAL,
        storage_location=f"file://{ROOT}/landing",
        comment="Order exports dropped by the partner SFTP job",
    )
)
print(landing.full_name, landing.storage_location)

The location must be a directory below a bucket or container root, not the root itself. It must not overlap another table or volume, and it must not contain __unitystorage, the prefix the server uses for managed storage.

Required privileges: USE_CATALOG on the catalog (or ownership of it), plus ownership of the schema or USE_SCHEMA and CREATE_VOLUME on it. If the location falls inside an external location, you also need CREATE_EXTERNAL_VOLUME on that external location, or ownership of it.

Create a managed volume

Leave out the location. The server allocates one below the schema's storage root or, if the schema has none, the catalog's.

volumes.pyFull script
reports = await volumes.create_volume(
    CreateVolumeRequestContent(
        catalog_name="retail",
        schema_name="files",
        name="reports",
        volume_type=VolumeType.MANAGED,
    )
)
print(reports.storage_location)  # allocated under the schema's storage root

The allocated path has the form <storage root>/__unitystorage/schemas/<schema id>/volumes/<volume id>. The server records the path but doesn't create the directory; it appears when the first file is written there. If neither the schema nor the catalog has a storage root, the request fails with None of catalog, schema or storage-root.tables server property has managed location configured.

Required privileges: the same as for an external volume, without the external-location check.

View volumes

volumes.pyFull script
listed = await volumes.list_volumes(catalog_name="retail", schema_name="files")
print([(v.name, v.volume_type) for v in listed.volumes or []])

info = await volumes.get_volume(name="retail.files.landing")
print(info.storage_location, info.comment)

Required privileges: READ_VOLUME or ownership on the volume, plus USE_SCHEMA and USE_CATALOG. Owners of the schema (with USE_CATALOG), the catalog, or the metastore can also view it. A list returns only the volumes you could get.

Work with the files

A volume's metadata tells a client where its files are. The client then reads and writes them with ordinary storage tools.

With local file:// storage, the location is a directory you can use directly:

volumes.pyFull script
path = Path(info.storage_location.removeprefix("file://"))
print(sorted(p.relative_to(path).as_posix() for p in path.rglob("*")))

On cloud storage, a client needs credentials for the location. A client with the right privileges can request temporary credentials scoped to a volume from the server; see Credential vending. Open source Unity Catalog doesn't provide the /Volumes/<catalog>/<schema>/<volume> paths that Databricks compute mounts. Clients work with the volume's storage_location.

Rename or update a volume

Change the comment, or rename the volume with new_name. Renaming changes only the volume's name. Its files and location stay the same.

volumes.pyFull script
renamed = await volumes.update_volume(
    name="retail.files.landing",
    update_volume_request_content=UpdateVolumeRequestContent(
        new_name="partner_landing",
        comment="Partner order exports, retained 30 days",
    ),
)
print(renamed.full_name)  # retail.files.partner_landing

Required privileges: ownership of the volume, plus USE_CATALOG (or ownership) on the catalog and USE_SCHEMA (or ownership) on the schema.

Delete a volume

volumes.pyFull script
await volumes.delete_volume(name="retail.files.partner_landing")
await volumes.delete_volume(name="retail.files.reports")

What happens to the files depends on the volume type:

Volume typeCatalog entryFiles
ExternalDeletedLeft in place. Delete them with your storage tools if you no longer need them.
ManagedDeletedThe server deletes the volume's directory after server.storage-cleanup.initial-delay, 7 days by default.

Required privileges: ownership of the catalog; or ownership of the schema plus USE_CATALOG; or ownership of the volume plus USE_CATALOG and USE_SCHEMA.

Next steps