datacube-core is a catalog over satellite data, and Postgres is the dependency that matters
Open Data Cube analyses continental scale Earth Observation data through time
At a glance
- What is it?
- opendatacube/datacube-core is an Apache-2.0 Python package that gives an integrated gridded data analysis environment over decades of analysis ready earth observation data, with the product index held in PostgreSQL or PostGIS and the raster work done by rasterio, xarray, dask and numpy. The README also documents the constraint that shapes every deployment, PostgreSQL 15 and newer, and a migration path between the 1.8 and 1.9 series.
- Who is it for?
- Adopt datacube-core if your work involves querying a catalogue of satellite products, where each observation needs to be found by time, space and product type before it can be analysed, because that index is the part the library adds over plain raster processing. Do not adopt it for a one-off analysis of a handful of files, since a database, a migration tool and a plugin framework are a large setup for that.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An analysis environment over decades of observation data
The Open Data Cube Core provides an integrated gridded data analysis environment for decades of analysis ready earth observation satellite and related data from multiple satellite and other acquisition systems. That phrase hides the real design. A gridded analysis environment is not a viewer and not a downloader. It assumes that the data is already ingested, indexed and described, so that a query can ask for every observation of a given product type over a bounding box and a time range, and get back a set of datasets that can be loaded and combined. The package is Python, and the topic tags say what it works on: gdal, gis, netcdf, numpy, raster, remote-sensing and scientific-computing. The project is a component rather than a complete system, with the documentation on readthedocs, a Discord for support, a code of conduct, and a project site at opendatacube.org. The README also states that this is a 1.9.x series release, and that anyone migrating from a 1.8.x release should read the 1.8.x to 1.9.x migration notes.
The stated requirements and the manifest disagree about Python
The Requirements section of the README lists PostgreSQL 15+ and Python 3.10+. The package manifest in the same repository is stricter than that. It sets requires-python to 3.12 or newer, and the classifier list names Python 3.12, 3.13 and 3.14 only, with no 3.10 or 3.11 entry. The development setup section uses a conda environment file, and the Ubuntu instructions build a virtual environment with python3 -m venv, both of which take whatever interpreter you give them, so the 3.10 claim in the README is the kind of thing that is easy to act on and then fail on. The honest summary is that the manifest is the binding constraint, and the README's requirement line is out of date. The PostgreSQL half is not ambiguous, and the compose file goes further, using a postgis/postgis image at 18-3.6, which is a PostGIS build rather than a plain server.
The developer setup is a conda env and an editable install
The documented setup clones the repository, creates a Python environment, installs a development version of the package and wires up the pre-commit hooks. The README recommends Mambaforge as the easiest way to handle the Python dependencies, and the commands are:
mamba env create -f conda-environment.yml
conda activate cubeenvthen, from inside the checkout, an editable install of the package with its dev group, and the hooks:
cd datacube-core
pip install --upgrade -e . --group dev pre-commit installTests are run through a shell script rather than by hand, and the README explains that the script approximates what GitHub Actions runs, with pytest as the alternative:
``./check-code.sh``The integration variant needs a database, and the requirement is specific. It assumes the existence of two password-less Postgres databases running on localhost called pgintegration and pgisintegration, and the alternative is to copy integration_tests/integration.conf to ~/.datacube_integration.conf and edit it. The version of the package being installed also matters, because the dev group is what supplies the test dependencies, and if that install fails the README asks you to lodge an issue.
Docker removes the database setup entirely
The alternative to provisioning two password-less Postgres databases is the datacube-tests image, which includes a database server pre-configured for running integration tests. You add the --with-docker command line option as the first argument to the check-code.sh script:
./check-code.sh --with-docker integration_testsTo run individual tests in a container, the README builds a local image from the repository's Dockerfile and runs pytest against a mounted working directory:
docker build --tag=opendatacube/datacube-tests-local --no-cache --progress plain -f docker/Dockerfile . docker run -ti -v $(pwd):/code opendatacube/datacube-tests-local:latest pytest integration_tests/test_filename.py::test_function_nameThe value of this route is that the two-database arrangement, which exists because the tests need a plain Postgres index and a PostGIS index at the same time, is packaged rather than documented. For a contributor the cost of getting it wrong is an afternoon, and for a continuous integration pipeline the image is the sane default.
The Ubuntu path builds the environment by hand
There is a separate section for Ubuntu, and it is the one to read if you are not using conda, because the system libraries are not optional. The install list covers the build tooling and the geospatial libraries:
sudo apt-get install -y \
autoconf automake build-essential make cmake \
graphviz \
python3-venv \
python3-dev \
libpq-dev \
libyaml-dev \
libnetcdf-dev \
libudunits2-devThe netcdf, udunits and yaml development packages are there for the raster and metadata stack, libpq is for the database client, and graphviz is the documentation toolchain. The environment itself is a plain virtual environment created with python3 -m venv under a pyenv directory, and the install ends with an editable install of the package and its dev group. Two details in the sequence are worth noting. The first line of the environment section upgrades pip, wheel, cython and numpy before the package install, which suggests the build needs a recent numpy and a compiled extension, and the pyenv variable is set to a path under your home directory that the README says to change to suit your needs.
The dependency list is the geospatial stack, and the pins are deliberate
The manifest's dependency list is the clearest statement of what this project actually does. It includes affine and rasterio for raster access, xarray and dask for array shaped work over data that does not fit in memory, pyproj and shapely for geometry, pandas for tabular work, and GeoAlchemy2 with SQLAlchemy for the spatial database layer. Around those sit the Open Data Cube family packages, odc-geo, odc-loader and odc-stac, which is what turns raw NetCDF into the product objects the index stores. Several version constraints carry comments explaining the reason, and they are the ones to read before you upgrade anything. antimeridian is held below 0.4.5 because all test_index_cloning tests fail with that version, SQLAlchemy is held at 2.0 and below 2.1 because GeoAlchemy2 requires 1.4 or newer, rasterio is at least 1.4.4 to handle changes in recent versions of GDAL, and xarray is above 0.9 to fix most problems with crs attributes being lost. That last comment is a good example of what this library does. The hard problem in a catalogue is not reading pixels, it is keeping the coordinate reference system attached to the data.
The index driver is a configuration choice you have to make
The compose file for the test stack is where the architecture becomes concrete, because it sets every index driver as an environment variable. There are four real ones, ODC_DATACUBE_INDEX_DRIVER and ODC_POSTGIS_INDEX_DRIVER for the 1.x pair, and ODC_DATACUBE3_INDEX_DRIVER and ODC_POSTGIS3_INDEX_DRIVER for the 3.x pair, with the plain postgres driver and the postgis driver as the values. Alongside them are deliberate negative cases, ODC_NOSUCHDRIVERENV_INDEX_DRIVER set to a value named no_such_driver, each with a matching ODC_*_DB_URL variable, and those exist so the test suite can prove the code fails loudly on a bad driver name rather than silently connecting to the wrong place. The URLs themselves are ordinary SQLAlchemy connection strings, with the psycopg driver prefix on the 3.x pair. The database is a postgis/postgis image on port 35432 with a named volume for the data directory, and the two databases pgintegration and pgisintegration are created by a script mounted into the container's init directory.
Where a plain raster stack is the better answer
The realistic alternative is to skip the catalogue and work with the data directly, using rasterio and xarray over NetCDF files in an object store or a shared filesystem. The difference in approach is the index. A direct stack has no index, so finding the right observation means knowing where the file is and what it is called, and the metadata lives in a sidecar rather than in a queryable table. A catalogue has an index, which means you can ask for products by time, space and type, and it means every ingest needs a database write, a migration and a plugin that knows how to read the data. The trade is proportional to how much you query. If you analyse a handful of scenes once, the direct stack is less machinery and fewer failure modes. If you run a programme that queries the catalogue daily, or that has to be reproducible years later, the index and its migrations are what make the results reproducible. The Open Data Cube also costs you the plugin ecosystem, since reading a new product type means writing a loader against odc-loader, and the repository's examples/io_plugin/ directory is where that work starts.
Editorial conclusion
Adopt datacube-core if your work involves querying a catalogue of satellite products, where each observation needs to be found by time, space and product type before it can be analysed, because that index is the part the library adds over plain raster processing. Do not adopt it for a one-off analysis of a handful of files, since a database, a migration tool and a plugin framework are a large setup for that. Before you deploy, confirm PostgreSQL 15 or newer is available and decide whether the index driver is postgres or postgis, and read the 1.8 to 1.9 migration notes before upgrading an existing installation, since the project ships them separately from the user guide.
Frequently asked questions
What is the Open Data Cube Core?
It is an Apache-2.0 Python package that provides an integrated gridded data analysis environment for decades of analysis ready earth observation satellite and related data from multiple acquisition systems, with a product index held in PostgreSQL or PostGIS and the raster work handled by rasterio, xarray, dask and numpy.
What does the Open Data Cube require?
The README lists PostgreSQL 15+ and Python 3.10+, but the package manifest is stricter, with requires-python set to 3.12 or newer and classifiers for 3.12, 3.13 and 3.14. The test compose file uses a postgis/postgis 18-3.6 image, so PostGIS is expected in the stack as well as plain PostgreSQL.
How do I run the Open Data Cube integration tests?
The script ./check-code.sh runs the unit tests and PyLint, and ./check-code.sh integration_tests adds the integration tests, which assume two password-less Postgres databases on localhost named pgintegration and pgisintegration. Alternatively, the datacube-tests Docker image has the database pre-configured, and adding the --with-docker option as the first argument to the script uses it.
How do I set up a development environment for the Open Data Cube?
Clone the repository, create a conda environment with mamba env create -f conda-environment.yml and activate it, then install the package in development mode with pip install --upgrade -e . --group dev and run pre-commit install. The Ubuntu instructions instead build a virtual environment with python3 -m venv after installing system libraries including libpq-dev, libnetcdf-dev and libudunits2-dev.
Which Open Data Cube index drivers exist?
The test compose file sets ODC_DATACUBE_INDEX_DRIVER and ODC_POSTGIS_INDEX_DRIVER for the 1.x pair and ODC_DATACUBE3_INDEX_DRIVER and ODC_POSTGIS3_INDEX_DRIVER for the 3.x pair, with postgres and postgis as the driver values, plus deliberate no_such_driver cases used to check that a bad driver name fails loudly.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/opendatacube-datacube-core)Was this useful?