Skip to main content

Convert graph data from DuckDB to CSR format for Icebug

Project description

Icebug Format

Note: This project was formerly called graph-std.

Icebug is a standardized graph format designed for efficient graph data interchange. It comes in two formats:

  • icebug-disk: Parquet-based format for object storage
  • icebug-memory: Apache Arrow-based format for in-memory processing

This project provides tools to convert graph data from simple DuckDB databases or Parquet files containing nodes_* and edges_* tables, along with a schema.cypher file, into standardized graph formats for efficient processing.

Sample Usage

uv run icebug-format.py \
--source-db karate/karate_random.duckdb \
--output-db karate/karate_csr.duckdb \
--csr-table karate \
--schema karate/karate_csr/schema.cypher

This will create a CSR representation with multiple tables depending on the number of node and edge types:

  • {table_name}_indptr_{edge_name}: Array of size N+1 for row pointers (one per edge table)
  • {table_name}_indices_{edge_name}: Array of size E containing column indices (one per edge table)
  • {table_name}_nodes_{node_name}: Original nodes table with node attributes (one per node table)
  • {table_name}_mapping_{node_name}: Maps original node IDs to contiguous indices (one per node table)
  • {table_name}_metadata: Global graph metadata (node count, edge count, directed flag)
  • schema.cypher: A cypher schema that a graph database can mount without ingesting

More information about Icebug and Apache GraphAR

Blog Post

Recreating demo-db/icebug-disk

Start from a simple demo-db.duckdb that looks like this

Querying database: demo-db.duckdb
================================

--- Table: edges_follows ---
┌────────┬────────┬───────┐
│ source │ target │ since │
│ int32  │ int32  │ int32 │
├────────┼────────┼───────┤
│    100 │    250 │  2020 │
│    300 │     75 │  2022 │
│    250 │    300 │  2021 │
│    100 │    300 │  2020 │
└────────┴────────┴───────┘
================================

--- Table: edges_livesin ---
┌────────┬────────┐
│ source │ target │
│ int32  │ int32  │
├────────┼────────┤
│    100 │    700 │
│    250 │    700 │
│    300 │    600 │
│     75 │    500 │
└────────┴────────┘
================================

--- Table: nodes_city ---
┌───────┬───────────┬────────────┐
│  id   │   name    │ population │
│ int32 │  varchar  │   int64    │
├───────┼───────────┼────────────┤
│   500 │ Guelph    │      75000 │
│   600 │ Kitchener │     200000 │
│   700 │ Waterloo  │     150000 │
└───────┴───────────┴────────────┘
================================

--- Table: nodes_user ---
┌───────┬─────────┬───────┐
│  id   │  name   │  age  │
│ int32 │ varchar │ int64 │
├───────┼─────────┼───────┤
│   100 │ Adam    │    30 │
│   250 │ Karissa │    40 │
│    75 │ Noura   │    25 │
│   300 │ Zhang   │    50 │
└───────┴─────────┴───────┘
================================

--- Schema: schema.cypher --
CREATE NODE TABLE User(id INT64, name STRING, age INT64, PRIMARY KEY (id));
CREATE NODE TABLE City(id INT64, name STRING, population INT64, PRIMARY KEY (id));
CREATE REL TABLE Follows(FROM User TO User, since INT64);
CREATE REL TABLE LivesIn(FROM User TO City);

and run:

uv run icebug-format.py \
--directed \
--source-db demo-db.duckdb \
--output-db demo-db_csr.duckdb \
--csr-table demo \
--schema demo-db/schema.cypher

You'll get a demo-db_csr.duckdb AND the object storage ready representation aka icebug-disk.

Verification

You can verify that the conversion went ok by running scan.py. It's also a good way to understand the icebug-disk format.

uv run scan.py --input demo-db_csr --prefix demo
Metadata: 7 nodes, 8 edges, directed=True

Node Tables:

Table: demo_nodes_user
(100, 'Adam', 30)
(250, 'Karissa', 40)
(75, 'Noura', 25)
(300, 'Zhang', 50)

Table: demo_nodes_city
(500, 'Guelph', 75000)
(600, 'Kitchener', 200000)
(700, 'Waterloo', 150000)

Edge Tables (reconstructed from CSR):

Table: follows (FROM user TO user)
(100, 250, 2020)
(100, 300, 2020)
(250, 300, 2021)
(300, 75, 2022)

Table: livesin (FROM user TO city)
(75, 500)
(100, 700)
(250, 700)
(300, 600)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

icebug_format-0.1.0.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

icebug_format-0.1.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file icebug_format-0.1.0.tar.gz.

File metadata

  • Download URL: icebug_format-0.1.0.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for icebug_format-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ef7cccbc94a69bcf17fd63fa42a5540d0c074a37c82e9ececb2e7b9fe2822c36
MD5 275933de812250bc1c3980b0167036ee
BLAKE2b-256 d970959a0d5c42512dc6510d04062d7ca2eb3a7a704199d73a9658ceb91f90d2

See more details on using hashes here.

File details

Details for the file icebug_format-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: icebug_format-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for icebug_format-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2dbcd419735979e44124fdde965cbc0005bb7d6f91770f11c73a5a7be062b833
MD5 6cd2f4f9cecfcc8e8cb76bb0e4e40c77
BLAKE2b-256 1c55e772390efc97470f66ca583eea875617064529b344b1de63785b02ca2dad

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page