Skip to main content

Synopsis

chameleon introspect <database-url> [flags]
Introspect an existing database and generate a ChameleonDB schema.

Description

The introspect command:
  1. Connects to existing database - Uses provided connection string
  2. Scans all tables - Detects user tables, columns, types
  3. Generates schema - Creates ChameleonDB .cham schema file
  4. Respects paranoid mode - Blocked in readonly mode
  5. Handles overwrites safely - Prompts before replacing existing schemas
Supported databases:
  • ✅ PostgreSQL
  • 🚧 MySQL (coming soon)
  • 🚧 SQLite (coming soon)

Arguments

database-url
string
required
Database connection string or environment variable referenceFormats:
  • Direct URL: postgresql://user:pass@localhost/db
  • Env variable: $DATABASE_URL
  • Env variable: ${DATABASE_URL}
  • Env variable: env:DATABASE_URL

Flags

-o, --output
string
default:"schema.cham"
Output file path (auto-prefixed with schemas/)
chameleon introspect postgresql://... -o myschema.cham
Result: schemas/myschema.cham
-f, --force
boolean
default:"false"
Force overwrite without confirmation
chameleon introspect postgresql://... --force
Warning: Use with caution. Overwrites existing schema without backup.

Examples

Basic Introspection

chameleon introspect postgresql://user:password@localhost/mydb
Output:
ℹ Paranoid Mode active: standard
ℹ Introspecting database...
✓ Database detected
ℹ Scanning tables...
✓ Found 3 table(s)
ℹ Generating schema...
✓ Schema written to schemas/schema.cham

ℹ Next steps:
  1. Review schema and adjust relations manually
  2. Run: chameleon validate
  3. Use with your application

Custom Output File

chameleon introspect postgresql://localhost/blog -o blog.cham
Output:
✓ Schema written to schemas/blog.cham

Using Environment Variable

export DATABASE_URL="postgresql://user:password@localhost/mydb"
chameleon introspect $DATABASE_URL
Or:
chameleon introspect '${DATABASE_URL}'
chameleon introspect env:DATABASE_URL

Force Overwrite

chameleon introspect postgresql://localhost/mydb --force
Output:
✓ Schema written to schemas/schema.cham (overwritten)

Before Introspection

Existing Database

PostgreSQL tables:
CREATE TABLE users (
    id UUID PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    name VARCHAR(255),
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE posts (
    id UUID PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    content TEXT,
    author_id UUID REFERENCES users(id),
    published BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW()
);

After Introspection

Generated Schema

schemas/schema.cham:
entity User {
    id: uuid primary,
    email: string unique,
    name: string,
    created_at: timestamp default now(),
}

entity Post {
    id: uuid primary,
    title: string,
    content: string,
    author_id: uuid,
    published: bool default false,
    created_at: timestamp default now(),
}

Manual Adjustments

You may need to add relationships manually:
entity User {
    id: uuid primary,
    email: string unique,
    name: string,
    posts: [Post] via author_id,  // Added manually
    created_at: timestamp default now(),
}

entity Post {
    id: uuid primary,
    title: string,
    content: string,
    author_id: uuid,
    author: User,  // Added manually
    published: bool default false,
    created_at: timestamp default now(),
}

Paranoid Mode Behavior

Readonly Mode (Default)

chameleon introspect postgresql://localhost/mydb
Error:
❌ Read Only Paranoid Mode is active - introspection is blocked

ℹ Mode upgrade available:
   1. Run: chameleon config auth set-password
   2. Run: chameleon config set mode=standard
   3. Retry: chameleon introspect <database-url>

❌ readonly mode: introspect is blocked

Standard Mode

# Upgrade mode first
chameleon config set mode=standard

# Now introspection works
chameleon introspect postgresql://localhost/mydb
 Schema written to schemas/schema.cham

Overwrite Protection

Default Schema Detected

If schemas/schema.cham contains the default schema from chameleon init:
chameleon introspect postgresql://localhost/mydb
Output:
⚠️  Found default schema.cham from 'chameleon init'

ℹ File exists: schemas/schema.cham
Overwrite? (yes/no): yes
✓ Schema written to schemas/schema.cham

Modified Schema Detected

If schemas/schema.cham has custom entities:
chameleon introspect postgresql://localhost/mydb
Output:
❌ Found modified schema.cham with custom entities!

⚠️  This appears to be a working schema file

ℹ Existing schema detected: schemas/schema.cham

Options:
  1. Create backup and overwrite (recommended)
  2. Use different output file
  3. Cancel

Choose option (1-3): 1
✓ Backup created: schemas/schema.cham.backup
✓ Schema written to schemas/schema.cham

Using Different Output File

Choose option (1-3): 2
Enter new output file path: introspected.cham
ℹ Auto-added .cham extension: introspected.cham
ℹ Auto-prefixed with schemas/: schemas/introspected.cham
✓ Schema written to schemas/introspected.cham

Connection String Formats

PostgreSQL

# Full URL
chameleon introspect "postgresql://user:password@localhost:5432/dbname"

# Without password (prompts)
chameleon introspect "postgresql://user@localhost/dbname"

# Unix socket
chameleon introspect "postgresql:///dbname?host=/var/run/postgresql"

# SSL mode
chameleon introspect "postgresql://user:pass@host/db?sslmode=require"

Environment Variable References

# Using $
chameleon introspect $DATABASE_URL

# Using ${}
chameleon introspect '${DATABASE_URL}'

# Using env: prefix
chameleon introspect env:DATABASE_URL

Error Handling

Connection Failed

chameleon introspect postgresql://localhost/mydb
Error:
❌ failed to connect to database: connection refused

ℹ Check:
   - Database is running
   - Connection string is correct
   - Network connectivity

Database Not Detected

chameleon introspect mysql://localhost/mydb
Error:
❌ failed to detect database type

ℹ Supported:
   - PostgreSQL (postgresql://)
   - MySQL (coming soon)
   - SQLite (coming soon)

No Tables Found

chameleon introspect postgresql://localhost/emptydb
Output:
✓ Database detected
ℹ Scanning tables...
✓ Found 0 table(s)
ℹ Generating schema...
✓ Schema written to schemas/schema.cham

⚠️  Warning: No tables found in database
Generated schema:
// No tables found in database

Permission Denied

chameleon introspect postgresql://user@localhost/mydb
Error:
❌ failed to scan tables: permission denied

ℹ Ensure database user has SELECT permissions:
   GRANT SELECT ON ALL TABLES IN SCHEMA public TO user;

Type Mapping

PostgreSQL to ChameleonDB

PostgreSQLChameleonDB
UUIDuuid
VARCHAR, TEXTstring
INTEGER, BIGINTint
BOOLEANbool
TIMESTAMP, TIMESTAMPTZtimestamp
NUMERIC, DECIMALdecimal
JSONB, JSONjson

Limitations

Not Detected

  • Relationships - Foreign keys detected but not converted to relations
  • Indexes - Not included in schema
  • Triggers - Not supported
  • Views - Only tables are introspected
  • Constraints - Only PRIMARY and UNIQUE detected

Manual Post-Processing

After introspection, you may need to:
  1. Add relationships:
    posts: [Post] via author_id,
    author: User,
    
  2. Add indexes:
    @index([email])
    
  3. Refine types:
    // Change generic 'string' to more specific types
    email: string,  // Could be: email: string @format(email)
    

Best Practices

1. Introspect to New File

chameleon introspect postgresql://... -o introspected.cham
Preserves existing schema for comparison.

2. Review Before Committing

# Generate schema
chameleon introspect postgresql://localhost/mydb

# Review changes
cat schemas/schema.cham

# Validate
chameleon validate

# Commit
git add schemas/schema.cham
git commit -m "Add introspected schema"

3. Use in CI/CD

# .github/workflows/introspect.yml
name: Introspect Database
on:
  schedule:
    - cron: '0 0 * * 0'  # Weekly
jobs:
  introspect:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Introspect
        run: |
          chameleon introspect ${{ secrets.DATABASE_URL }} -o weekly.cham
      - name: Create PR if changes
        run: |
          git diff --exit-code schemas/weekly.cham || \
            gh pr create --title "Schema drift detected"

See Also