Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Configuration File Format

Deflatable uses a YAML configuration file to specify database connections and view configurations.

File Structure

database: <sqlalchemy-url>
table_order:
  - <table-name>
  - <table-name>

settings:
  display:
    reverse_fk_preview_items: <number>
    cell_truncation_length: <number>
  grouping:
    recommendations:
      max_distinct_values: <number>
      max_cardinality_ratio: <ratio>

views:
  <table-name>:
    active_view: <view-name>
    record_links:
      <fk-column>:
        display_name: <custom-name>
        lookup_fields:
          - <field-name>
    views:
      <view-name>:
        visible_fields: [<column>, ...]
        grouping: <column>
        sort_config: [[<column>, <direction>], ...]
        filters: [[<column>, <operator>, <value>, <logic>], ...]

Required Fields

database

Type: String Required: Yes Description: SQLAlchemy database URL

Examples:

# SQLite (relative path)
database: sqlite:///database.db

# SQLite (absolute path)
database: sqlite:////absolute/path/to/database.db

# PostgreSQL
database: postgresql://user:password@localhost:5432/dbname

# MySQL
database: mysql://user:password@localhost/dbname

# DuckDB
database: duckdb:///data.duckdb

Optional Fields

table_order

Type: Array of strings Required: No Description: Specifies the order tables appear in tabs

By default, tables are displayed in alphabetical order. Use table_order to customize this.

Example:

table_order:
  - product
  - order
  - customer

Tables not listed in table_order will appear after the specified tables in alphabetical order.

settings

Type: Object Required: No Description: Global application settings for display and grouping behavior

The settings section contains configuration for how Deflatable displays data and recommends grouping options.

settings.display

Type: Object Description: Controls display behavior for table cells and related records

Available options:

Example:

settings:
  display:
    reverse_fk_preview_items: 3
    cell_truncation_length: 100
    group_header_style: "bold cyan"
    group_header_bg_style: "on blue"

settings.grouping

Type: Object Description: Controls how Deflatable recommends columns for grouping

When you create or edit a view, Deflatable suggests which columns are suitable for grouping based on these criteria.

settings.grouping.recommendations

Available options:

Example:

settings:
  grouping:
    recommendations:
      max_distinct_values: 100  # Stricter - only recommend low-cardinality columns
      max_cardinality_ratio: 0.5  # Only recommend if < 50% unique values
      min_distinct_values: 3  # Require at least 3 distinct values
      excluded_types:
        - BLOB
        - BINARY
        - FLOAT

Complete settings example:

database: sqlite:///mydb.db

settings:
  display:
    reverse_fk_preview_items: 3
    cell_truncation_length: 120
  grouping:
    recommendations:
      max_distinct_values: 150
      max_cardinality_ratio: 0.6

views:
  # ... table views ...

views

Type: Object Required: No Description: Named view configurations per table

Each table can have multiple saved views.

View Configuration

views.<table-name>

Each table can have:

active_view

Type: String Default: "All" Description: Name of the currently active view for this table

Type: Object Optional: Yes Description: Configuration for foreign key relationships to display related table data

Record links allow you to show fields from related tables inline, without writing joins.

Format:

record_links:
  <fk_column>:
    display_name: <custom-name>  # Optional
    lookup_fields:
      - field: <field-name>
        display_name: <custom-name>  # Optional
      - <field-name>  # Shorthand form

Example:

product:
  record_links:
    aisle_id:
      display_name: "Aisle"
      lookup_fields:
        - field: "refrigerated"
          display_name: "Is Refrigerated"
        - "length_feet"  # Uses default display name

This creates virtual columns in the product table:

These lookup columns can be used in:

views.<view-name>

Each view object can contain:

visible_fields

Type: Array of strings Description: List of column names to display Default: All columns

visible_fields: [id, name, price]

grouping

Type: String Description: Column name to group rows by Default: null (no grouping)

grouping: aisle_id

sort_config

Type: Array of [column, direction] tuples Description: Sort order specification Default: [] (no sorting)

Direction values: "asc" or "desc"

sort_config:
  - [price, desc]
  - [name, asc]

filters

Type: Array of [column, operator, value, logic] tuples Description: Filter conditions Default: [] (no filters)

Format: [column, operator, value, logic]

Operators:

Logic (for multiple filters):

filters:
  - [price, ">", "3.00", "and"]
  - [aisle_id, "=", "2", "and"]

Complete Example

database: sqlite:///grocery.db
table_order:
  - product
  - aisle

settings:
  display:
    reverse_fk_preview_items: 2
    cell_truncation_length: 80
  grouping:
    recommendations:
      max_distinct_values: 200
      max_cardinality_ratio: 0.7
      min_distinct_values: 2

views:
  product:
    active_view: Expensive Products
    record_links:
      aisle_id:
        display_name: "Aisle"
        lookup_fields:
          - field: "refrigerated"
            display_name: "Is Refrigerated"
          - "length_feet"
    views:
      All:
        visible_fields: [id, name, aisle_id, aisle_id__refrigerated, price]
        sort_config: []
        filters: []

      "Expensive Products":
        visible_fields: [name, price, aisle_id, aisle_id__refrigerated]
        grouping: null
        sort_config:
          - [price, desc]
        filters:
          - [price, ">", "3.00", "and"]

      "Dairy Products":
        visible_fields: [id, name, price]
        filters:
          - [aisle_id, "=", "2", "and"]
        sort_config:
          - [name, asc]

  aisle:
    active_view: All
    views:
      All:
        visible_fields: [id, length_feet, refrigerated, has_endcaps]

File Location

Config files can be placed anywhere. Specify the path when running:

deflatable /path/to/config.yaml

Creating Config Files

Use the init command:

deflatable init <config-file> <database-url>

Example:

deflatable init mydb.yaml sqlite:///mydb.db

Modifying Configuration

Manual Editing

Edit the YAML file directly with any text editor.

From Within Deflatable

  1. Make changes (filters, sorts, etc.)

  2. Click ViewSave to update the current view

  3. Or click ViewSave As to create a new view

Changes are written back to the config file.

Validation

Validate your config file:

deflatable validate config.yaml

Output formats:

Quiet mode (exit code only):

deflatable validate config.yaml --quiet

Path Handling

Relative Paths (SQLite)

Relative to the config file’s directory:

# config.yaml in /home/user/project/
database: sqlite:///data/db.sqlite

# Resolves to: /home/user/project/data/db.sqlite

Absolute Paths

Use absolute paths for databases outside the project:

database: sqlite:////var/data/production.db

Remote Databases

PostgreSQL, MySQL, and other network databases use full URLs:

database: postgresql://user:pass@db.example.com:5432/production

Schema Changes

When your database schema changes (new tables, columns, etc.):

  1. Deflatable automatically detects new tables

  2. New columns appear in existing tables

  3. Views referencing deleted columns/tables will show errors

  4. Update or remove outdated view configurations manually

Security

Do Not Commit Credentials: For production databases with passwords, use environment variables:

database: postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_NAME}

Then set environment variables before running:

export DB_USER=myuser
export DB_PASS=mypassword
export DB_HOST=localhost
export DB_NAME=mydb
deflatable config.yaml

Troubleshooting

“Cannot connect to database”

“Table not found in views”

“Column not found”