Skip to main content

Intelligent SQL to NoSQL schema migration - analyzes query patterns to recommend optimal MongoDB schema design

Project description

๐Ÿงญ Schema Travels

Intelligent SQL โ†’ MongoDB Schema Migration

"Stop guessing embed vs. reference. Let your query patterns decide."

CI Python 3.10+ License: MIT PyPI version


The Problem

Migrating from PostgreSQL/MySQL to MongoDB? You'll face this question hundreds of times:

"Should I embed this data or reference it?"

Most migration tools do 1:1 table-to-collection mapping โ€” which completely ignores why you're moving to NoSQL in the first place.

The right answer depends on how you actually access your data. But manually analyzing thousands of queries? Nobody has time for that.

The Solution

Schema Travels analyzes your real query patterns and recommends an optimal MongoDB schema:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Query Logs     โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚  Pattern Analysis โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚  AI-Powered     โ”‚
โ”‚  + SQL Schema   โ”‚     โ”‚  โ€ข Hot joins      โ”‚     โ”‚  Recommendationsโ”‚
โ”‚                 โ”‚     โ”‚  โ€ข Co-access %    โ”‚     โ”‚  โ€ข EMBED        โ”‚
โ”‚                 โ”‚     โ”‚  โ€ข Write ratios   โ”‚     โ”‚  โ€ข REFERENCE    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Result: A MongoDB schema optimized for your access patterns โ€” not generic "best practices."


What's New in v1.2.0

๐ŸŽ›๏ธ Cache Modes

Control how sensitive the cache is to log changes:

# Relaxed (default): Ignores small log changes
# Cache invalidates only on significant pattern changes
schema-travels analyze --cache-mode relaxed ...

# Strict: Any change in query counts = fresh recommendations  
schema-travels analyze --cache-mode strict ...
Scenario Relaxed Strict
2 extra log lines โœ… Cache hit โŒ Fresh AI call
New join pair found โŒ Fresh AI call โŒ Fresh AI call
Schema DDL changed โŒ Fresh AI call โŒ Fresh AI call

๐Ÿ”„ Reproducible Results with Caching (v1.1.0)

Same inputs now produce the same recommendations every time:

# First run - calls Claude API
schema-travels analyze --logs-dir ./logs --schema-file ./schema.sql
# โ†’ Cached to ~/.schema-travels/cache/

# Second run - uses cache (instant, consistent)
schema-travels analyze --logs-dir ./logs --schema-file ./schema.sql
# โ†’ Same recommendations, no API call

# Force fresh analysis
schema-travels analyze --logs-dir ./logs --schema-file ./schema.sql --no-cache

๐Ÿ”‘ Better API Key Errors (v1.1.0)

Clear, actionable error when API key is missing:

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚                    โš ๏ธ  API KEY NOT CONFIGURED                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Schema Travels requires an Anthropic API key for AI-powered       โ”‚
โ”‚  schema recommendations.                                            โ”‚
โ”‚                                                                     โ”‚
โ”‚  Option 1: export ANTHROPIC_API_KEY=sk-ant-xxxxx                   โ”‚
โ”‚  Option 2: echo "ANTHROPIC_API_KEY=sk-ant-xxxxx" > .env            โ”‚
โ”‚                                                                     โ”‚
โ”‚  Get your API key at: https://console.anthropic.com/settings/keys  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Quick Start

Installation

pip install schema-travels

Basic Usage

# Set your API key
export ANTHROPIC_API_KEY=sk-ant-xxxxx

# Analyze your database
schema-travels analyze \
    --logs-dir ./postgresql-logs \
    --schema-file ./schema.sql \
    --target mongodb \
    --output results.json

What You Get

๐Ÿ“Š Analysis Summary
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Hot Joins (Top 5):
  users โŸท orders      : 12,847 calls, 8.3ms avg
  orders โŸท order_items: 11,203 calls, 5.1ms avg  
  products โŸท reviews  : 8,456 calls, 12.7ms avg

Recommendations:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Parent      โ”‚ Child       โ”‚ Decision  โ”‚ Confidence โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ users       โ”‚ addresses   โ”‚ EMBED     โ”‚ 92%        โ”‚
โ”‚ orders      โ”‚ order_items โ”‚ EMBED     โ”‚ 87%        โ”‚
โ”‚ users       โ”‚ orders      โ”‚ REFERENCE โ”‚ 85%        โ”‚
โ”‚ products    โ”‚ reviews     โ”‚ REFERENCE โ”‚ 78%        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why Schema Travels?

โŒ What Other Tools Do

SQL Table          โ†’    MongoDB Collection
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
users              โ†’    users
addresses          โ†’    addresses  
orders             โ†’    orders
order_items        โ†’    order_items

This is just PostgreSQL with different syntax.

โœ… What Schema Travels Does

// users collection โ€” addresses embedded (92% co-accessed)
{
  _id: ObjectId("..."),
  email: "user@example.com",
  name: "John Doe",
  addresses: [                    // โ† EMBEDDED (bounded, rarely updated)
    { street: "123 Main", city: "NYC", is_default: true }
  ]
}

// orders collection โ€” items embedded, user referenced
{
  _id: ObjectId("..."),
  user_id: ObjectId("..."),       // โ† REFERENCED (accessed independently)
  status: "shipped",
  items: [                        // โ† EMBEDDED (always fetched together)
    { product_id: "...", quantity: 2, price: 29.99 }
  ]
}

Features

๐Ÿ“Š Access Pattern Analysis

  • Hot Join Detection โ€” Find frequently co-accessed tables
  • Co-access Ratios โ€” Measure how often tables are queried together
  • Write Ratio Tracking โ€” Identify update-heavy tables (bad embed candidates)
  • Solo Access Detection โ€” Find independently accessed entities

๐Ÿค– AI-Powered Recommendations

  • Claude Integration โ€” Intelligent embed/reference decisions
  • Confidence Scores โ€” Know how certain each recommendation is
  • Detailed Reasoning โ€” Understand why each decision was made
  • Warning Detection โ€” Get alerts for potential issues

๐Ÿ”„ Reproducible Results (v1.1.0+)

  • Recommendation Caching โ€” Same inputs = same outputs
  • Cache Modes โ€” relaxed ignores small log changes, strict for precision (v1.2.0)
  • Version Tracking โ€” Cache auto-invalidates when logic changes
  • Comparison Tools โ€” Diff recommendations between runs
  • Cache Control โ€” --no-cache for fresh analysis

โšก Migration Simulation

  • Storage Impact โ€” Estimate size changes from embedding
  • Latency Projection โ€” Predict query performance improvements
  • Cost Estimation โ€” Calculate infrastructure cost differences

๐Ÿ“ˆ Visualization

  • HTML Reports โ€” Interactive schema visualization
  • Mermaid Diagrams โ€” ER diagrams for documentation
  • Console Output โ€” Rich terminal formatting

How It Works

1. Collect Access Patterns

Schema Travels parses your PostgreSQL/MySQL query logs:

2024-01-15 10:30:45 LOG: statement: SELECT u.*, a.* FROM users u 
    JOIN addresses a ON u.id = a.user_id WHERE u.id = 123
2024-01-15 10:30:45 LOG: duration: 3.45 ms

2. Analyze Patterns

For each table relationship, it calculates:

Metric Description Embed Signal
Co-access ratio % of queries accessing both tables High = Embed
Child independence % of queries accessing child alone High = Reference
Write ratio % of operations that are writes High = Reference
Cardinality Avg/max children per parent High = Reference

3. Apply Decision Rules

# Simplified decision logic
if max_children > 1000:
    return REFERENCE  # Unbounded = always reference

if co_access > 70% and write_ratio < 30% and max_children < 100:
    return EMBED      # High co-access, low writes, bounded

if child_independence > 40%:
    return REFERENCE  # Accessed alone too often

if write_ratio > 50%:
    return REFERENCE  # Too many updates

4. Generate Schema

Output includes:

  • MongoDB collection definitions
  • Embedded document structures
  • Reference relationships
  • Sample documents

Configuration

Environment Variables

# Required for AI recommendations
export ANTHROPIC_API_KEY=sk-ant-xxxxx

# Optional
export ANTHROPIC_MODEL=claude-sonnet-4-20250514  # or claude-opus-4-5-20250514
export LOG_LEVEL=INFO

Or create a .env file:

cp .env.example .env
# Edit .env with your API key

CLI Options

schema-travels analyze \
    --logs-dir ./logs           # Directory with query logs
    --schema-file ./schema.sql  # SQL DDL file
    --db-type postgres          # postgres or mysql
    --target mongodb            # Target database
    --output results.json       # Output file
    --use-ai                    # Enable AI recommendations (default)
    --no-ai                     # Use rule-based only
    --cache-mode relaxed        # relaxed (default) or strict
    --no-cache                  # Bypass recommendation cache
    --clear-cache               # Clear all cached recommendations

Commands

Command Description
schema-travels analyze Run full analysis
schema-travels report --analysis-id <id> View previous analysis
schema-travels history List all analyses
schema-travels simulate --analysis-id <id> Run migration simulation
schema-travels config Show current configuration

Input Requirements

Query Logs

PostgreSQL โ€” Enable in postgresql.conf:

log_statement = 'all'
log_duration = on
log_line_prefix = '%t [%p] %u@%d '

MySQL โ€” Enable slow query log:

slow_query_log = 1
long_query_time = 0
log_queries_not_using_indexes = 1

Schema File

Standard SQL DDL:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) NOT NULL
);

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id),
    total DECIMAL(10,2)
);

Storage Locations

~/.schema-travels/
โ”œโ”€โ”€ schema_travels.db     # Analysis history (SQLite)
โ””โ”€โ”€ cache/
    โ”œโ”€โ”€ index.json        # Cache index with metadata
    โ””โ”€โ”€ <hash>.json       # Cached recommendations

Example Output

Recommendations JSON

{
  "recommendations": [
    {
      "parent_table": "users",
      "child_table": "addresses",
      "decision": "EMBED",
      "confidence": 0.92,
      "reasoning": [
        "92% co-access ratio",
        "Low write frequency (8%)",
        "Bounded cardinality (avg 2.1, max 5)"
      ],
      "warnings": []
    }
  ]
}

Generated MongoDB Schema

// users collection
{
  $jsonSchema: {
    bsonType: "object",
    required: ["email"],
    properties: {
      email: { bsonType: "string" },
      name: { bsonType: "string" },
      addresses: {
        bsonType: "array",
        items: {
          bsonType: "object",
          properties: {
            street: { bsonType: "string" },
            city: { bsonType: "string" },
            zip: { bsonType: "string" }
          }
        }
      }
    }
  }
}

Architecture

schema-travels/
โ”œโ”€โ”€ src/schema_travels/
โ”‚   โ”œโ”€โ”€ collector/      # Log parsing, schema extraction
โ”‚   โ”œโ”€โ”€ analyzer/       # Pattern detection (hot joins, mutations)
โ”‚   โ”œโ”€โ”€ recommender/    # AI recommendations, schema generation, caching
โ”‚   โ”œโ”€โ”€ simulator/      # Migration impact estimation
โ”‚   โ”œโ”€โ”€ persistence/    # SQLite storage for history
โ”‚   โ””โ”€โ”€ cli/            # Command-line interface
โ”œโ”€โ”€ tools/              # Workload generator, visualizer
โ”œโ”€โ”€ examples/           # Sample schemas and logs
โ””โ”€โ”€ tests/              # Test suite

Development

# Clone
git clone https://github.com/kraghavan/schema-travels.git
cd schema-travels

# Setup
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"

# Test
pytest --cov=schema_travels

# Lint
ruff check src/
ruff format src/

Roadmap

  • PostgreSQL log parsing
  • MySQL log parsing
  • MongoDB schema generation
  • Claude AI integration
  • Migration simulation
  • Recommendation caching (v1.1.0)
  • Cache modes - relaxed/strict (v1.2.0)
  • DynamoDB support
  • Web UI dashboard
  • Real-time log streaming
  • Multi-database analysis

Contributing

Contributions welcome! Please read CONTRIBUTING.md first.


License

MIT License โ€” see LICENSE for details.


Acknowledgments


Stop guessing. Start measuring.
โญ Star on GitHub

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

schema_travels-1.2.0.tar.gz (62.5 kB view details)

Uploaded Source

Built Distribution

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

schema_travels-1.2.0-py3-none-any.whl (61.0 kB view details)

Uploaded Python 3

File details

Details for the file schema_travels-1.2.0.tar.gz.

File metadata

  • Download URL: schema_travels-1.2.0.tar.gz
  • Upload date:
  • Size: 62.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for schema_travels-1.2.0.tar.gz
Algorithm Hash digest
SHA256 3afffa20f7b8ac1623eafa2ee9d3184c2db111fdca29ef5606ae114a7f7c3045
MD5 1f047ebb13351ed853cc2addb9dd6c4a
BLAKE2b-256 c926bb8455c7abf302720a1be03e41e4a544c5fe1a7f857310b80f2c6ff7a202

See more details on using hashes here.

File details

Details for the file schema_travels-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: schema_travels-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 61.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for schema_travels-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a6fddc50c27e68daf38d15c078fe47fb0635861551cc359f7699e57a2741ffbd
MD5 8e9311649c6821fbe5439d87978ed39a
BLAKE2b-256 a6d0658b358e6eb10280c70677f1603767b40b2a7819c896862d7871c7113e85

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