# Playground

Edit the Python source or the schema below: sqlty checks, types and highlights the queries as you type. It runs in your browser. The engine is compiled to [WebAssembly](<https://webassembly.org/>), and no code leaves the page.

Example Dialect  PostgreSQL MySQL SQLite  Fix all Rewrite Strip Format Copy link  A− A+ Present Open in playground

 ← → ↺ Reset

queries.py schema.sql sqlty.toml

Notes Problems Types JSON

- Loading the engine...

The file tabs above the editor switch between the files `sqlty check` reads:

| File | What it holds | On your machine |
| --- | --- | --- |
| `queries.py` | The Python source: diagnostics under the code with their quick fixes, SQL highlighted in query strings, completion and hover in queries | [`sqlty server`](<https://sqlty.kuncar.dev/recipes/vscode/index.md>) |
| `schema.sql` | The `CREATE TABLE` statements the queries are typed against | [`schema`](<https://sqlty.kuncar.dev/reference/configuration/#schema>) |
| `sqlty.toml` | The `dialect`, `import-style`, `param-types` and `rules` of [`[tool.sqlty]`](<https://sqlty.kuncar.dev/reference/configuration/index.md>); its `dialect` wins over the select | `sqlty.toml` or `pyproject.toml` |

The console below the editor shows what sqlty makes of them:

| Tab | What it shows | From the command line |
| --- | --- | --- |
| Notes | What a step says about itself, when [steps](<#walk-through-steps>) are open |  |
| Problems | What `sqlty check` reports; click one to go to its line, or its rule to read about it | [`sqlty check`](<https://sqlty.kuncar.dev/reference/cli/index.md>) |
| Types | The row type, columns and parameters of each query, and the inference rule behind a column's type or nullability | `sqlty check --explain` |
| JSON | The problems as `sqlty check` prints them for scripts, with the edits of their fixes | [`sqlty check --output-format json`](<https://sqlty.kuncar.dev/reference/cli/index.md>) |

## Examples

The **Example** select loads a project of the [`examples/`](<https://github.com/jirikuncar/sqlty/tree/main/examples>) directory: its `queries.py`, `schema.sql`, and the `dialect`, `import-style`, `param-types` and `rules` of its `pyproject.toml`. Each one is what `sqlty check` reads on your machine, so the page shows the same problems. **Tour** is the sample the page opens with, and **Tour in steps** walks through the same ideas one at a time.

Drag the bar between the editor and the console to share the height between them, or focus it and press the arrow keys. The page remembers the height and the font size.

## Change the source

| Button | Applies to the Python source | From the command line |
| --- | --- | --- |
| **Fix all** | Every quick fix, as `sqlty check --fix` makes them | `sqlty check --fix` |
| **Rewrite** | Each query wrapped in `SQL[T]` | `sqlty rewrite` |
| **Strip** | Each `SQL[T]` wrapper removed | `sqlty strip` |
| **Format** | Each triple-quoted query laid out by [sqruff](<https://sqlty.kuncar.dev/guide/formatting/index.md>) | `sqlty format` |

A single fix is a quick fix on its diagnostic: click the light bulb, or press **Ctrl+.** with the cursor on it. **Ctrl+Z** undoes any of them.

## Offline

The docs work offline once they are open: a service worker keeps every page, and the playground once you have opened it. In Chrome or Edge, **Install** in the address bar adds SQLTy as an app; in Safari, **Share** then **Add to Home Screen** (iOS) or **File** then **Add to Dock** (macOS). The app opens the docs, with the playground among its shortcuts, and keeps it ready offline from its first start. Steps from `?steps=<url>` need that URL to be reachable; a file opened or dropped on the page does not.

## Open a docs example

Each Python example of these docs has a **Playground** link under it. It opens the example here with the schema and the `[tool.sqlty]` settings of its page, so you can edit it and see what changes. An example that needs a helper module, or a setting that reads files, has no link.

## Share a session

The page keeps the Python source, the schema, the dialect and `sqlty.toml` in its URL, compressed, as you type. **Copy link** puts that URL on the clipboard: paste it in a bug report and whoever opens it sees what you see. Nothing is sent to a server, as the session lives in the part of the URL after `#`.

A session that compresses to more than 8000 characters gets no link: many browsers and chat apps cut longer URLs.

## Embed

Add `?embed` to a link to show only the editor, the console and **Fix all**, with **Open in playground** for the other controls. It fills the window, so it fits an `<iframe>` in a blog post or slides:

```html
<iframe src="https://sqlty.kuncar.dev/playground/?embed#..." width="800" height="500"></iframe>
```

Link previews in social apps show the SQLTy card, not the session: their crawlers never see the part of the URL after `#`.

## Walk through steps

Steps are sessions in order, each one built on the one before: a talk, a lesson or a code review, played in the page. The bar above the files moves between them, and **Reset** brings the current step back to how it started, so a step can be edited live without losing it.

Load steps from **Open a file...** in the **Example** select, by dropping a `.json` file on the playground, or with a link: `playground/?steps=<url>` loads the file at that URL, which must allow [cross-origin requests](<https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS>), as `raw.githubusercontent.com` and `gist.githubusercontent.com` do. Once loaded, the steps are part of the session, so **Copy link** shares them while they fit in a link.

```json
{
  "title": "Nullable joins",
  "steps": [
    {
      "title": "A LEFT JOIN",
      "schema": "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL);",
      "source": "q = \"--sql\\nSELECT name FROM users\"\n",
      "panel": "types",
      "notes": "Each column is typed from the schema."
    },
    { "title": "A typo", "source": "q = \"--sql\\nSELECT nme FROM users\"\n", "panel": "problems" }
  ]
}
```

| Key | What it sets | When it is left out |
| --- | --- | --- |
| `title` | The name of the step in the bar | `Step N` |
| `source`, `schema`, `config`, `dialect` | The files and dialect, as a [session](<#share-a-session>) holds them | The one of the step before |
| `panel` | The console tab it opens: `notes`, `problems`, `types` or `json` | The tab open before, or **Problems** if that was **Notes** and the step has none |
| `file` | The file tab it opens: `python`, `schema` or `config` | The file open before |
| `notes` | Text for the **Notes** tab; a blank line starts a paragraph | No **Notes** tab |

## Present

**Present** fills the screen with the playground, and **A−** and **A+** change the font size of the editor and the console, for a projector or a screen share.

| Keys | What they do |
| --- | --- |
| **Ctrl+Shift+F** | Present, or stop presenting; **Escape** also stops |
| **Ctrl+=**, **Ctrl+-** | A larger or a smaller font |
| **PageDown**, **PageUp** | The next or the previous step, as most presentation remotes send |

On macOS, **Command** works as **Ctrl**.

> [!NOTE]
>
> **Row types from classes need Python**
>
> The playground reads `tuple[...]` row types. A `TypedDict`, dataclass or Pydantic model is resolved by the Python half of sqlty, which does not run in the browser, so `sqlty check` can report more on your machine. Keys of `sqlty.toml` that name files, such as `schema` and `overrides`, are errors here.
