MeridianMERIDIAN
Datasets

Use Anywhere

One ATTACH line exposes the whole catalogue to DuckDB, Python and R, reading the same file the browser reads. Or read a Parquet file directly, or download it.

The browser explorer is a convenience, not a walled garden. Every dataset is a plain Parquet file at a stable URL, and the whole catalog is a frozen DuckLake — so you can query it from a notebook, a script, or a scheduled job with one line.

One line to the whole catalog

ATTACH 'ducklake:https://openlake.meridian.online/catalog/open.ducklake' AS meridian (READ_ONLY);

That attaches the open catalog read-only and exposes every dataset as a schema-qualified table. There is one schema per namespace: an issuer's namespace, which Meridian holds for datasets it maintains from that issuer's public files (gleif, sec, census), or library for datasets Meridian made itself:

TableWhat it is
meridian.gleif.leiGLEIF legal entities (LEI register)
meridian.sec.company_tickers_exchangeSEC EDGAR company tickers
meridian.census.naics_2022NAICS industry classification, 2022 edition
meridian.library.edgar_leiEDGAR ↔ GLEIF crosswalk (CIK ↔ LEI)

The name no longer says whether a dataset is raw or derived from others; the dataset's page says so.

The catalog is a single ~5 MB file that points at the underlying Parquet by reference — attaching it copies no data. Your engine reads only the columns and row groups each query needs, straight from R2.

The snippets

These do what the explorer's Use elsewhere drawer does, with the full table name written out. The query shown is the GLEIF country breakdown from the quick start.

-- One ATTACH exposes every Meridian open dataset as a table.
INSTALL ducklake;
ATTACH 'ducklake:https://openlake.meridian.online/catalog/open.ducklake' AS meridian (READ_ONLY);
SELECT country, count(*) AS entities
FROM meridian.gleif.lei
GROUP BY country
ORDER BY entities DESC
LIMIT 20;

-- Or read just this one Parquet directly:
INSTALL httpfs;
SELECT country, count(*) AS entities
FROM read_parquet('https://openlake.meridian.online/gleif/lei.parquet')
GROUP BY country
ORDER BY entities DESC
LIMIT 20;
import duckdb

con = duckdb.connect()
con.execute("INSTALL ducklake; INSTALL httpfs;")
con.execute("ATTACH 'ducklake:https://openlake.meridian.online/catalog/open.ducklake' AS meridian (READ_ONLY)")
df = con.sql("""
SELECT country, count(*) AS entities
FROM meridian.gleif.lei
GROUP BY country
ORDER BY entities DESC
LIMIT 20
""").df()

# Or read just this one Parquet directly:
# duckdb.sql("""
# SELECT country, count(*) AS entities
# FROM read_parquet('https://openlake.meridian.online/gleif/lei.parquet')
# GROUP BY country
# ORDER BY entities DESC
# LIMIT 20
# """).df()

Requires the duckdb package: pip install duckdb.

library(duckdb)

con <- dbConnect(duckdb())
dbExecute(con, "INSTALL ducklake; INSTALL httpfs;")
dbExecute(con, "ATTACH 'ducklake:https://openlake.meridian.online/catalog/open.ducklake' AS meridian (READ_ONLY)")
dbGetQuery(con, "
SELECT country, count(*) AS entities
FROM meridian.gleif.lei
GROUP BY country
ORDER BY entities DESC
LIMIT 20
")

# Or read just this one Parquet directly:
# dbGetQuery(con, "
# SELECT country, count(*) AS entities
# FROM read_parquet('https://openlake.meridian.online/gleif/lei.parquet')
# GROUP BY country
# ORDER BY entities DESC
# LIMIT 20
# ")

Requires the duckdb package: install.packages("duckdb").

# DuckDB CLI — the whole commons via one ATTACH
duckdb -c "
  INSTALL ducklake;
  ATTACH 'ducklake:https://openlake.meridian.online/catalog/open.ducklake' AS meridian (READ_ONLY);
  SELECT country, count(*) AS entities FROM meridian.gleif.lei GROUP BY country ORDER BY entities DESC LIMIT 20;"

# Or read just this one Parquet directly:
# duckdb -c "INSTALL httpfs; SELECT country, count(*) AS entities FROM read_parquet('https://openlake.meridian.online/gleif/lei.parquet') GROUP BY country ORDER BY entities DESC LIMIT 20;"

Extension requirements

The engine needs two DuckDB extensions, both fetched on first use:

  • ducklake — resolves the ducklake: catalog. Install with INSTALL ducklake;. It pulls in HTTP support automatically, so the ATTACH line above works on its own.
  • httpfs — reads a Parquet file directly over HTTPS. Install with INSTALL httpfs;. You only need it for the read_parquet('https://…') fallback path.

Both live in the default extension repositories; a recent DuckDB (these snippets were checked on DuckDB 2.0.0) installs them without any extra configuration. INSTALL runs once and caches the extension locally.

ATTACH vs. read_parquet directly

Two ways in, and they answer different questions:

  • ATTACH the catalog when you want the whole commons behind one connection — stable table names (meridian.gleif.lei, meridian.library.edgar_lei, …), joins across datasets, and no per-file URLs to track.
  • read_parquet('https://openlake.meridian.online/<namespace>/<name>.parquet') when you want exactly one dataset and nothing else. The <namespace>/<name>.parquet URL is stable and always resolves to the current release.

Reproducible reads

The stable <namespace>/<name>.parquet URL follows the latest release. If you need a fixed snapshot that never changes under you, use the content-addressed URL from the manifest instead — see Data & provenance.

Just download the file

No SQL engine handy? The Parquet is an ordinary object — curl it:

# Resolve the current immutable URL from the manifest, then download it:
curl -s https://openlake.meridian.online/manifest.json | jq -r '.datasets["gleif/lei"].url'

# Or grab the stable pointer directly (follows the latest release):
curl -O https://openlake.meridian.online/gleif/lei.parquet

A note on the corpus column

Each table carries a hidden corpus column — a normalized blend of the text columns that powers the explorer's search box. SELECT * will include it (and it's large). When you want the clean, human columns, list them explicitly or exclude it:

SELECT * EXCLUDE (corpus) FROM meridian.gleif.lei LIMIT 50;

Old addresses

Until 31 October 2026 the datasets had flat names. Those names still work, so a query or script written against them keeps running for now:

Old SQL nameOld fileNew SQL nameNew file
meridian.source.gleif, meridian.gleifhttps://openlake.meridian.online/gleif.parquetmeridian.gleif.leihttps://openlake.meridian.online/gleif/lei.parquet
meridian.source.edgar, meridian.edgarhttps://openlake.meridian.online/edgar.parquetmeridian.sec.company_tickers_exchangehttps://openlake.meridian.online/sec/company_tickers_exchange.parquet
meridian.source.naics, meridian.naicshttps://openlake.meridian.online/naics.parquetmeridian.census.naics_2022https://openlake.meridian.online/census/naics_2022.parquet
meridian.crosswalk.edgar_gleif, meridian.edgar_gleifhttps://openlake.meridian.online/edgar_gleif.parquetmeridian.library.edgar_leihttps://openlake.meridian.online/library/edgar_lei.parquet

They do not behave the same way:

  • The old SQL names are views over the new tables, so they return the same, current rows.
  • The old files, and the old keys in the manifest (gleif, edgar, naics, edgar_gleif), are frozen: they hold the release they had on 31 October 2026 and get no new ones.

Both stay readable until an end date that is not set yet. It will be set once the Brightfield release that reads the new addresses is out, and it will be at least 90 days after that release. Move to the new names before then; the new ones are the ones that follow each release.

On this page