home / skills / benchflow-ai / skillsbench / sqlite-map-parser

This skill parses SQLite databases into structured JSON by exploring schemas, identifying relations, and transforming data into consumable maps.

npx playbooks add skill benchflow-ai/skillsbench --skill sqlite-map-parser

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.1 KB
---
name: sqlite-map-parser
description: Parse SQLite databases into structured JSON data. Use when exploring unknown database schemas, understanding table relationships, and extracting map data as JSON.
---

# SQLite to Structured JSON

Parse SQLite databases by exploring schemas first, then extracting data into structured JSON.

## Step 1: Explore the Schema

Always start by understanding what tables exist and their structure.

### List All Tables
```sql
SELECT name FROM sqlite_master WHERE type='table';
```

### Inspect Table Schema
```sql
-- Get column names and types
PRAGMA table_info(TableName);

-- See CREATE statement
SELECT sql FROM sqlite_master WHERE name='TableName';
```

### Find Primary/Unique Keys
```sql
-- Primary key info
PRAGMA table_info(TableName);  -- 'pk' column shows primary key order

-- All indexes (includes unique constraints)
PRAGMA index_list(TableName);

-- Columns in an index
PRAGMA index_info(index_name);
```

## Step 2: Understand Relationships

### Identify Foreign Keys
```sql
PRAGMA foreign_key_list(TableName);
```

### Common Patterns

**ID-based joins:** Tables often share an ID column
```sql
-- Main table has ID as primary key
-- Related tables reference it
SELECT m.*, r.ExtraData
FROM MainTable m
LEFT JOIN RelatedTable r ON m.ID = r.ID;
```

**Coordinate-based keys:** Spatial data often uses computed coordinates
```python
# If ID represents a linear index into a grid:
x = id % width
y = id // width
```

## Step 3: Extract and Transform

### Basic Pattern
```python
import sqlite3
import json

def parse_sqlite_to_json(db_path):
    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row  # Access columns by name
    cursor = conn.cursor()

    # 1. Explore schema
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
    tables = [row[0] for row in cursor.fetchall()]

    # 2. Get dimensions/metadata from config table
    cursor.execute("SELECT * FROM MetadataTable LIMIT 1")
    metadata = dict(cursor.fetchone())

    # 3. Build indexed data structure
    data = {}
    cursor.execute("SELECT * FROM MainTable")
    for row in cursor.fetchall():
        key = row["ID"]  # or compute: (row["X"], row["Y"])
        data[key] = dict(row)

    # 4. Join related data
    cursor.execute("SELECT * FROM RelatedTable")
    for row in cursor.fetchall():
        key = row["ID"]
        if key in data:
            data[key]["extra_field"] = row["Value"]

    conn.close()
    return {"metadata": metadata, "items": list(data.values())}
```

### Handle Missing Tables Gracefully
```python
def safe_query(cursor, query):
    try:
        cursor.execute(query)
        return cursor.fetchall()
    except sqlite3.OperationalError:
        return []  # Table doesn't exist
```

## Step 4: Output as Structured JSON

### Map/Dictionary Output
Use when items have natural unique keys:
```json
{
  "metadata": {"width": 44, "height": 26},
  "tiles": {
    "0,0": {"terrain": "GRASS", "feature": null},
    "1,0": {"terrain": "PLAINS", "feature": "FOREST"},
    "2,0": {"terrain": "COAST", "resource": "FISH"}
  }
}
```

### Array Output
Use when order matters or keys are simple integers:
```json
{
  "metadata": {"width": 44, "height": 26},
  "tiles": [
    {"x": 0, "y": 0, "terrain": "GRASS"},
    {"x": 1, "y": 0, "terrain": "PLAINS", "feature": "FOREST"},
    {"x": 2, "y": 0, "terrain": "COAST", "resource": "FISH"}
  ]
}
```

## Common Schema Patterns

### Grid/Map Data
- Main table: positions with base properties
- Feature tables: join on position ID for overlays
- Compute (x, y) from linear ID: `x = id % width, y = id // width`

### Hierarchical Data
- Parent table with primary key
- Child tables with foreign key reference
- Use LEFT JOIN to preserve all parents

### Enum/Lookup Tables
- Type tables map codes to descriptions
- Join to get human-readable values

## Debugging Tips

```sql
-- Sample data from any table
SELECT * FROM TableName LIMIT 5;

-- Count rows
SELECT COUNT(*) FROM TableName;

-- Find distinct values in a column
SELECT DISTINCT ColumnName FROM TableName;

-- Check for nulls
SELECT COUNT(*) FROM TableName WHERE ColumnName IS NULL;
```

Overview

This skill parses SQLite databases into clean, structured JSON to help you explore unknown schemas, reveal table relationships, and extract map-style data. It focuses on schema discovery, safe querying, and assembling joined or computed records into usable JSON objects or arrays. Use it to convert grid or hierarchical database layouts into interoperable JSON for analysis, visualization, or export.

How this skill works

The parser first inspects sqlite_master and PRAGMA outputs to list tables, columns, indexes, and foreign keys. It then reads metadata (dimensions, config) and builds an indexed data structure from a chosen main table. Related tables are joined by primary/foreign keys or by computed coordinates, and missing tables are handled gracefully. Finally, it emits either a keyed map or an ordered array JSON structure depending on the data shape.

When to use it

  • You need to explore an unfamiliar SQLite database before designing queries or migrations.
  • You want to extract map or grid data (tiles, coordinates) as JSON for visualization.
  • You need to combine main records with related tables into a single JSON payload.
  • You want a safe, repeatable way to export hierarchical or enum-based schemas.
  • You need to compute (x,y) from linear IDs and include spatial coordinates in JSON.

Best practices

  • Start by listing tables and inspecting PRAGMA table_info and foreign_key_list for each table.
  • Read a single-row config or metadata table for dimensions (width/height) before computing coordinates.
  • Build a dictionary keyed by a stable identifier (ID or computed x,y) to merge related rows safely.
  • Use LEFT JOIN logic or separate passes to preserve parent records even when children are missing.
  • Handle missing tables and SQL errors with safe_query wrappers to keep the export resilient.

Example use cases

  • Convert a game's tile database into a JSON map containing metadata, tiles by x,y, and overlay features.
  • Export a content management DB with parent articles and child comments into JSON arrays for an API.
  • Inspect an unknown dataset: list tables, sample rows, map enums to human-readable values, and export.
  • Transform sensor logs stored with linear IDs into coordinate-tagged JSON for geospatial plotting.

FAQ

Should I output an object map or an array?

Use a keyed map when items have unique natural keys (like x,y or GUIDs). Use an array when order matters or keys are simple integers.

How do I handle computed coordinates from a linear ID?

Read width/height from metadata, then compute x = id % width and y = id // width and include those in each JSON record.