Parquet Files¶
Links: Monthly Full Bundles · Weekly Full Bundles · Weekly Deltas · How Releases Work
Want to query the files, not just download them?
This page covers where the Parquet files live and how to keep a set current. Query the Data teaches querying them: a live in-browser console, every table's columns, how the tables join, and runnable recipes.
Parquet is derived from the bundle and overwritten every release
The JSON bundles are the release record. Parquet is a convenience: every value in it can be recomputed from the bundle. One Parquet dataset is published, rebuilt every release (weekly) from the newest weekly release and overwritten in place. There are no dated, per-delta or archived Parquet sets.
The dataset lives at one stable path, v1/1.1/parquet/, one file per section, with a manifest.json beside it:
v1/1.1/parquet/
{section}.parquet 22 files, one per bundle section
manifest.json build date, source release and dataset, builder, schema version, each file's size and sha256,
and the ClinVar source, attribution, disclaimer and license scope
The manifest also carries the data's provenance: source (ClinVar at NCBI, its data use policy and a citation), attribution, disclaimer and license (CC0 scope), matching Data Use and Citation. The manifest names the release the dataset was built from, so check it before comparing results with a bundle (the index's Parquet entry carries the same source_release). For an earlier state, see Earlier releases.
The latest set¶
Available Parquet files¶
Each Parquet file contains one bundle section with typed, query-friendly columns extracted from the JSON objects. Nearly every section includes an id column (the object identifier) and a data column (the full JSON object as a string), plus additional typed columns for key fields — enabling efficient filtering and aggregation without parsing JSON. The exception: therapy and therapyGroup name the id column key and hold the JSON object in value. Before 1.1.0, condition had no data column and therapy / therapyGroup had only key and value. The column reference lists every column of every section.
Available Parquet files (22 sections):
| File | Description |
|---|---|
sequenceReference.parquet |
NCBI RefSeq sequence references |
location.parquet |
VRS SequenceLocation records |
allele.parquet |
VRS Allele records |
copyNumberCount.parquet |
VRS CopyNumberCount records |
copyNumberChange.parquet |
VRS CopyNumberChange records |
gene.parquet |
Gene records (MappableConcept with NCBI Gene / HGNC codings) |
variation.parquet |
CategoricalVariant records (Cat-VRS) |
condition.parquet |
Condition records (traits) |
conditionSet.parquet |
ConditionSet records (trait sets) |
therapy.parquet |
Therapy records (drug therapies, content-addressed) |
therapyGroup.parquet |
TherapyGroup records (combination therapies) |
submitter.parquet |
Submitter organization records |
propositionPathogenicity.parquet |
Pathogenicity propositions |
propositionOncogenicity.parquet |
Oncogenicity propositions |
propositionSomaticClinicalImpact.parquet |
Somatic clinical impact propositions (ClinicalSignificance, and the Diagnostic, Prognostic and TherapeuticResponse targets of SCI evidence lines) |
propositionClinvarCustom.parquet |
ClinVar custom propositions (the Clinvar* types) |
evidenceLine.parquet |
SCV evidence line records |
vcv_evidenceLine.parquet |
VCV evidence line records |
rcv_evidenceLine.parquet |
RCV evidence line records |
scv.parquet |
SCV statement records |
vcv.parquet |
VCV aggregate statement records |
rcv.parquet |
RCV aggregate statement records |
Working with Parquet Files¶
Download the Parquet files you need, then query them locally. The R2 hosting has rate limits and is designed for file downloads, not as a remote query endpoint for tools like DuckDB.
Prerequisites
The examples below use the DuckDB CLI and/or Python with pandas + pyarrow (pip install pandas pyarrow). If you don't already have these tools, install them from the linked pages first — each subsection also shows its own one-line install command.
Download¶
Download individual sections or all files at once:
Download sections with curl
# The one published Parquet dataset, overwritten every release; manifest.json names its release.
BASE="https://data.clinvar-gkm.org/v1/1.1/parquet"
mkdir -p clinvar-gkm-parquet && cd clinvar-gkm-parquet
curl -O "${BASE}/manifest.json"
# Download specific sections
curl -O "${BASE}/scv.parquet"
curl -O "${BASE}/propositionPathogenicity.parquet"
curl -O "${BASE}/condition.parquet"
# Or download all 22 sections
for section in sequenceReference location allele copyNumberCount copyNumberChange \
gene variation condition conditionSet therapy therapyGroup submitter \
propositionPathogenicity propositionOncogenicity propositionSomaticClinicalImpact propositionClinvarCustom \
evidenceLine vcv_evidenceLine rcv_evidenceLine \
scv vcv rcv; do
curl -O "${BASE}/${section}.parquet"
done
Query¶
DuckDB is the fastest way to explore Parquet files — it queries them directly with no data loading step. pandas + pyarrow works well when you want DataFrames.
Query with DuckDB / pandas
# Query SCV statements
duckdb -c "
SELECT id, classification.name AS classification, direction, strength.name AS strength, quality.name AS quality
FROM 'scv.parquet'
WHERE classification.name = 'Pathogenic'
LIMIT 10;
"
# Count classifications across all SCVs
duckdb -c "
SELECT classification.name AS classification, direction, COUNT(*) as n
FROM 'scv.parquet'
GROUP BY classification.name, direction
ORDER BY n DESC;
"
# Join SCVs with propositions to find pathogenic variants for a specific condition
duckdb -c "
SELECT s.id, s.classification.name AS classification, p.predicate, p.object_id
FROM 'scv.parquet' s
JOIN 'propositionPathogenicity.parquet' p ON s.proposition_id = p.id
WHERE s.classification.name = 'Pathogenic'
AND p.object_id = 'clinvar.trait:9580'
LIMIT 10;
"
DuckDB also works from Python:
import duckdb
df = duckdb.sql("""
SELECT id, classification.name AS classification, direction, strength.name AS strength, quality.name AS quality
FROM 'scv.parquet'
WHERE classification.name = 'Pathogenic'
LIMIT 100
""").df()
print(df)
With pandas / pyarrow:
import pandas as pd
# Load a section into a DataFrame
scv = pd.read_parquet("scv.parquet")
# Filter pathogenic SCVs — classification is a MappableConcept struct (dict), so read .name
pathogenic = scv[scv["classification"].map(lambda c: c and c.get("name")) == "Pathogenic"]
print(f"{len(pathogenic)} pathogenic SCVs")
# Access the full JSON when you need nested fields
import json
record = json.loads(pathogenic.iloc[0]["data"])
print(record["proposition"])
Column Reference¶
The complete per-table reference — every column, type and description for all 22 sections — is in Query the Data → The 22 Tables. A summary:
Statement sections (scv, vcv, rcv) share a common set of typed columns:
| Column | Type | Description |
|---|---|---|
id |
string | Statement identifier |
type |
string | Statement type |
proposition_id |
string | FK to the matching proposition Parquet — one of propositionPathogenicity, propositionOncogenicity, propositionSomaticClinicalImpact, propositionClinvarCustom, by the proposition's type; read_parquet('proposition*.parquet') covers all four |
classification |
struct (MappableConcept) | Use classification.name (or classification.primaryCoding.code) — e.g., "Pathogenic" |
strength |
struct (MappableConcept) | Use strength.name — e.g., "definitive", "likely" |
direction |
string | Evidence direction ("supports", "disputes", "neutral") |
quality |
struct (MappableConcept) | Use quality.name — submission level, e.g., "criteria provided" |
has_evidence_lines |
list\<string> | FK references to evidence line Parquet (evidenceLine for SCV, vcv_evidenceLine for VCV, rcv_evidenceLine for RCV) |
extensions |
string | JSON array of extensions |
data |
string | Full JSON object |
SCV statements include additional columns: description, contributions, reportedIn and specifiedBy. reportedIn is a list of citation Documents, one per ClinVar citation, and specifiedBy.reportedIn is the assertion method's Document. From 1.1.0 each Document also has name, documentType and extensions; see scv.
The four proposition tables share one column schema (from 1.1.0): id, type, predicate, subject_variant_id, object_id, object_type, condition_qualifier_id, gene_context_id, gene_context_name, submitted_gene_symbols, gene_context_source, mode_of_inheritance, penetrance and data, so read_parquet('proposition*.parquet') reads them as one table. This enables JOINs across statements, variants, and conditions without parsing JSON. See Gene context for what the gene context is (one representative gene per variant, not a submitter-asserted gene), and The shared columns for each column.
Run DESCRIBE in DuckDB to see the full schema for any section.
These examples demonstrate cross-section JOINs using typed columns. Most analytical queries can be answered without parsing JSON — the proposition's gene_context_name column carries the gene symbol directly, and the condition's primaryCoding struct carries the MedGen code. (These queries join scv.parquet to propositionPathogenicity.parquet; swap in read_parquet('proposition*.parquet') to include every kind of claim, since the four tables have the same columns.)
For how the sections join — including the columns that point at more than one table, where a single-table join silently drops rows — see Joining Tables; for task-oriented queries, see Recipes.
Example cross-section queries (SQL)
All SCVs for a gene — detailed view:
-- SCVs for BRCA1: classification, review status, condition
SELECT
s.id AS scv_id,
s.classification.name AS classification,
s.direction,
s.strength.name AS strength,
s.quality.name AS review_status,
p.gene_context_name AS gene,
c.name AS condition_name,
c.primaryCoding.code AS condition_code
FROM 'scv.parquet' s
JOIN 'propositionPathogenicity.parquet' p ON s.proposition_id = p.id
LEFT JOIN 'condition.parquet' c ON p.object_id = c.id
WHERE p.gene_context_name = 'BRCA1'
ORDER BY s.classification.name;
Classification summary for a gene:
-- Count SCVs by classification and review status for BRCA2
SELECT
p.gene_context_name AS gene,
s.classification.name AS classification,
s.quality.name AS review_status,
s.direction,
COUNT(*) AS scv_count
FROM 'scv.parquet' s
JOIN 'propositionPathogenicity.parquet' p ON s.proposition_id = p.id
WHERE p.gene_context_name = 'BRCA2'
GROUP BY ALL
ORDER BY scv_count DESC;
Restrict to submissions with criteria provided:
-- Only expert panel and criteria-provided SCVs for a gene
SELECT
s.id AS scv_id,
s.classification.name AS classification,
s.quality.name AS review_status,
c.name AS condition_name
FROM 'scv.parquet' s
JOIN 'propositionPathogenicity.parquet' p ON s.proposition_id = p.id
LEFT JOIN 'condition.parquet' c ON p.object_id = c.id
WHERE p.gene_context_name = 'TP53'
AND s.quality.name IN ('criteria provided', 'reviewed by expert panel')
ORDER BY s.classification.name;
Cross-gene comparison — classification breakdown for multiple genes:
-- Compare pathogenicity classification distributions across genes
SELECT
p.gene_context_name AS gene,
s.classification.name AS classification,
COUNT(*) AS n
FROM 'scv.parquet' s
JOIN 'propositionPathogenicity.parquet' p ON s.proposition_id = p.id
WHERE p.gene_context_name IN ('BRCA1', 'BRCA2', 'TP53', 'MLH1')
AND s.quality.name = 'criteria provided'
GROUP BY gene, s.classification.name
ORDER BY gene, n DESC;
Accessing fields not in typed columns — some fields, like submitter names, HGVS expressions, and assertion methods, are only available in the data column (full JSON string). Use DuckDB's json_extract_string to access them:
-- SCVs with submitter name and assertion method (from JSON)
SELECT
s.id AS scv_id,
s.classification.name AS classification,
p.gene_context_name AS gene,
json_extract_string(s.data, '$.contributions[0].agent.name') AS submitter,
json_extract_string(s.data, '$.specifiedBy.name') AS method
FROM 'scv.parquet' s
JOIN 'propositionPathogenicity.parquet' p ON s.proposition_id = p.id
WHERE p.gene_context_name = 'BRCA1'
AND s.classification.name = 'Pathogenic'
AND s.quality.name = 'reviewed by expert panel'
LIMIT 20;
When to use each access path:
| Approach | Best for | Tradeoff |
|---|---|---|
| Typed columns only | Filtering, counting, grouping, JOINs on classification, gene, condition, review status | Fast; covers most analytical questions |
Typed columns + json_extract_string |
Ad-hoc queries needing submitter names, HGVS, methods | Slightly slower; syntax is verbose |
Parse data column in application code |
Bulk processing needing many nested fields | Full flexibility; requires application-side JSON parsing |
Earlier releases¶
Only the current Parquet dataset is published; it is overwritten every release, and weekly deltas, archives and frozen lines carry no Parquet. To work with an earlier state:
- Rebuild it from the bundles. Every official monthly stays published (in
archive/YYYY/after its year ends) with a.sha256sidecar, and so does every delta. Rebuild the bundle for the week you need with the replay recipe, then read the sections you need. - Convert a bundle to Parquet with
clinvar-gkm-parquet(planned).clinvar-gkm-parquetis a separate, versioned tool that builds this Parquet layout from a published bundle and writes the samemanifest.json. It is in design and not yet released; until it is, earlier Parquet can't be downloaded or rebuilt in this layout. - The 1.0.1 generation is the frozen line
v1/1.0/: its bundles and delta manifests, with no Parquet.
Parquet downloaded from an earlier release keeps its old tables and columns; see the changelog for what changed.