Skip to main content
DuckDB is a single-node analytical database that runs inside your own process. Its iceberg extension connects to the Iceberg REST endpoint of a Wherobots-managed catalog, so you can read tables without starting a Wherobots runtime. Queries run on your machine, and DuckDB reads table files from cloud storage over the network. Wherobots issues the storage credentials for each table, so you don’t configure storage keys. The integration supports:
  • Reading Iceberg v2 and v3 tables, including tables with deleted rows.
  • Reading geometry columns, with or without a declared coordinate reference system (CRS). See Work with geometry.
The integration doesn’t support:
  • Changing existing tables. INSERT and DELETE fail with Forbidden_403 when DuckDB commits. Write to these tables from WherobotsDB instead.
  • Raster columns. Selecting a raster column, including with SELECT *, fails with Mismatch Type Error. Name the other columns in your query, or query raster data in WherobotsDB.
  • Foreign catalogs, such as AWS Glue or Databricks Unity Catalog. ATTACH fails with Unauthorized_401. To query them, connect WherobotsDB to external catalogs.
For the scope of this workflow and compatibility considerations, see Connect external engines to Wherobots catalogs.

Before you start

Ensure that you have the following:
  • Python with the duckdb package. The samples on this page ran on DuckDB 2.0.0.
  • Your Wherobots User ID, shown in Settings > Details, and a Wherobots API key that belongs to that user.
  • Access to the Wherobots-managed catalog you want to read. The samples on this page use the wherobots_open_data catalog.

Connect DuckDB to a Wherobots catalog

1

Install DuckDB

2

Find your catalog ID

List the catalogs you can access with your API key. Note the id of the catalog you want to read. Its type must be MANAGED:
3

Set your credentials

4

Request an access token

DuckDB’s built-in OAuth login fails against this endpoint, so request the token yourself and pass it to DuckDB. Replace YOUR_CATALOG_ID with the ID from the earlier step.
The token expires after one hour. To continue after that, see Troubleshooting.
5

Attach the catalog

Set DEFAULT_REGION to the AWS region of the catalog’s storage. The wherobots_open_data catalog is in us-west-2. DuckDB uses this region when the storage credentials from Wherobots don’t include one.
6

Verify the connection

The output lists tables in the overture_maps_foundation namespace, also known as a database:

Query a table

Refer to a table as <attached name>.<namespace>.<table>. This sample finds libraries in a bounding box around Boston:

Filter to read fewer files

DuckDB uses filters on plain columns and on GEOMETRY columns to skip data files, so the ST_Intersects filter in Query a table also reduces the files DuckDB reads. DuckDB doesn’t skip files for a filter on a column decoded from BLOB. On those tables, also filter on a plain column if one narrows the rows. To check how many files a query reads, run it with EXPLAIN ANALYZE and find Total Files Read in the plan. These counts come from test runs:

Save query results

COPY writes a result to a local file:

Work with geometry

The DuckDB column type depends on what the column declares. Run SHOW CREATE TABLE in WherobotsDB to see the declaration: Some tables have no declared CRS, such as the us_census.tiger_* tables in wherobots_open_data, and tables you created without one. To see the type in DuckDB, run DESCRIBE:
To read the CRS of a GEOMETRY value, use ST_CRS(geom). DuckDB has no ST_SRID function, and a value decoded from BLOB or VARCHAR has no CRS. To read the SRID that a column with no declared CRS stores, run ST_SRID(geom) in WherobotsDB. For example, the values in us_census.tiger_county have SRID 4269.

Troubleshooting

You created the secret with CLIENT_ID and CLIENT_SECRET. Create it with TOKEN instead, as Connect DuckDB to a Wherobots catalog shows.
ATTACH is missing the DEFAULT_REGION option. Add it with the AWS region of the catalog’s storage.
ATTACH fails with Unauthorized_401 when the token is invalid, when you pass the API key as TOKEN, or when the catalog is a foreign catalog. After a token expires, queries in an open session fail with an error that ends in "message":"Unauthorized".To continue with a managed catalog, request a new token and attach again:
If the token request itself returns invalid_client, the User ID and API key don’t match. Check that the key belongs to that user.
The column has no declared CRS, so DuckDB reads it as BLOB. Decode it first with ST_GeomFromWKB(geom).
The column declares a CRS, so DuckDB already reads it as GEOMETRY. Use the column directly, without ST_GeomFromWKB.
The CRS of your geometry doesn’t match the column. The fix depends on the coordinates in your geometry.If the coordinates are already in the column’s system, change only the label. A GEOMETRY(4326) column has the CRS OGC:CRS84, which DuckDB treats as different from EPSG:4326. Create the geometry with no CRS, as ST_MakeEnvelope(-71.19, 42.22, -70.92, 42.40) does, or set the matching CRS with ST_SetCRS(geometry, 'OGC:CRS84').If the coordinates are in another system, such as meters in EPSG:3857, convert them with ST_Transform. Changing the label leaves the coordinates as they are, so the query returns wrong results with no error. DuckDB 2.0 requires you to set the axis order before you call ST_Transform:

Next steps

Wherobots open data

Find the datasets in the wherobots_open_data catalog.

Geometry tables

Create tables with geometry columns that declare a CRS.

DuckDB iceberg extension

Learn the ATTACH options for Iceberg REST catalogs.