> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basecut.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# basecut snapshot restore

> Apply a snapshot's data to a target database

Restore downloads a snapshot and inserts its data into a target database. It validates schema compatibility and ensures referential integrity during the process.

<Info>
  Run your migrations first. Restore validates the target schema and inserts
  data; it does not create or alter tables.
</Info>

## Usage

```bash theme={null}
basecut snapshot restore <snapshot-ref> [flags]
```

***

## Arguments

| Argument         | Description                                                                             |
| ---------------- | --------------------------------------------------------------------------------------- |
| `<snapshot-ref>` | Snapshot identifier. Supported forms: UUID, `name:tag`, or `name` (resolves to latest). |

## Flags

| Flag                         | Default                        | Description                                                                                                                                                 |
| ---------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--target <url>, -t`         | `$BASECUT_TARGET_DATABASE_URL` | PostgreSQL connection string for the destination database. Restore does not use `BASECUT_DATABASE_URL` so you do not accidentally restore over your source. |
| `--reset`                    | `false`                        | Truncate snapshot-managed tables before applying (destructive).                                                                                             |
| `--force`                    | `false`                        | Skip schema validation (may fail if schemas are incompatible).                                                                                              |
| `--batch-size <n>`           | `1000`                         | Rows per insert batch (auto-capped per table by database limits).                                                                                           |
| `--on-conflict <mode>`       | `error`                        | Conflict behavior: `error` (fail fast) or `skip` (ignore conflicts).                                                                                        |
| `--analyze-fks`              | `false`                        | Run FK preflight analysis only (no data is applied).                                                                                                        |
| `--unsafe-disable-fk-checks` | `false`                        | Unsafe bypass: disables FK checks during restore (requires elevated DB privileges).                                                                         |
| `--yes, -y`                  | `false`                        | Skip confirmation prompts.                                                                                                                                  |
| `--profile <name>`           | `default`                      | Credential profile to use for API authentication.                                                                                                           |
| `--api-key <key>`            | `$BASECUT_API_KEY`             | API key override (otherwise uses `BASECUT_API_KEY` or saved profile).                                                                                       |

***

## Examples

### Quick Examples

```bash theme={null}
# Restore the latest version of a snapshot
basecut snapshot restore my-snapshot:latest \
  --target "postgresql://localhost:5432/myapp_test"

# Restore a specific version with a reset
basecut snapshot restore my-snapshot:brave-lion \
  --target "$BASECUT_TARGET_DATABASE_URL" \
  --reset

# Restore while skipping duplicate key conflicts
basecut snapshot restore my-snapshot:latest \
  --target "$BASECUT_TARGET_DATABASE_URL" \
  --on-conflict skip
```

***

### Basic Restore

Apply the latest version of a snapshot to your local database:

```bash theme={null}
basecut snapshot restore "weekly-dev-data" \
  --target "postgresql://localhost:5432/myapp_dev"
```

**What happens:**

1. CLI resolves the latest tag for "weekly-dev-data".
2. Downloads manifest and schema metadata.
3. Connects to the target database and validates schema compatibility.
4. Downloads data files and inserts rows in dependency order.
5. Verifies referential integrity across all restored tables.

***

### Clean Restore (Local Development)

Wipe existing data in the target tables before restoring:

```bash theme={null}
basecut snapshot restore "clean-seed" \
  --target "postgresql://localhost:5432/myapp_dev" \
  --reset \
  --yes
```

**When to use `--reset`:**

* You want to ensure the target tables only contain the snapshot data.
* You are re-running a seed script and want to avoid duplicate key errors.
* You want a clean slate for debugging a specific issue.

`--reset` runs inside the same transaction as restore inserts. If restore fails,
all reset and insert operations are rolled back together.

***

### CI/CD Integration

Automate restoration for integration tests:

```bash theme={null}
export BASECUT_API_KEY=bc_live_abc123_secret
export BASECUT_TARGET_DATABASE_URL=postgresql://test_user:pass@localhost:5432/test_db

basecut snapshot restore "ci-baseline:latest" --yes
```

***

### Analyze Foreign Key Restore Safety

Preview FK-related restore risk before applying any data:

```bash theme={null}
basecut snapshot restore "production:latest" \
  --target "$BASECUT_TARGET_DATABASE_URL" \
  --analyze-fks
```

`--analyze-fks` reports:

* Number of non-deferrable foreign key constraints.
* Self-referential tables in the restore scope.
* Whether an inter-table FK cycle exists.
* Whether safe restore mode would be blocked.
* Whether nullable fallback is available for blocking constraints.

If `Nullable fallback available: true`, Basecut will **automatically** handle the restore using a two-phase approach — inserting rows with temporary `NULL`s for the blocking FK columns, then backfilling the real values — with no additional flags required. This requires that all blocking FK columns are nullable and the affected table has a primary key or unique key.

Use this when preparing migrations or debugging FK restore blockers.

***

### Unsafe FK Bypass (Last Resort)

If you need a one-off restore and cannot make constraints deferrable immediately:

```bash theme={null}
basecut snapshot restore "production:latest" \
  --target "$BASECUT_TARGET_DATABASE_URL" \
  --unsafe-disable-fk-checks
```

<Warning>
  `--unsafe-disable-fk-checks` disables FK enforcement during restore. Use only in controlled environments and validate integrity after restore.
</Warning>

This mode may require elevated PostgreSQL privileges.

***

## Output

### Success

```bash theme={null}
✓ Loading snapshot: my-snapshot:brave-lion
✓ Validated schema for 23 tables
✓ Inserted 2,847 rows
✓ Verified referential integrity
✓ Restore complete in 3.2s
```

### With Reset

```bash theme={null}
⚠ Truncating 23 tables...
✓ Loading snapshot: my-snapshot:latest
✓ Validated schema for 23 tables
✓ Inserted 2,847 rows
✓ Restore complete
```

***

## Error Handling

### Schema Compatibility Error

```
✗ Error: schema mismatch detected
  Table 'users' is missing column 'last_login_at' which is present in snapshot.
```

**Solutions:**

* Run your database migrations to align the target schema with the snapshot.
* Use `--force` to skip validation (not recommended if data types have changed).

### Foreign Key Constraint Error

```
✗ Error: foreign key violation during restore on orders (orders_user_id_fkey)
```

**Common causes:**

* Non-deferrable foreign keys combined with cyclic or self-referential dependencies.
* Parent rows missing from target scope while child rows are restored.

**Solutions:**

* Run FK preflight first:

  ```bash theme={null}
  basecut snapshot restore "<snapshot-ref>" --target "$BASECUT_TARGET_DATABASE_URL" --analyze-fks
  ```

* Make relevant foreign key constraints `DEFERRABLE` where appropriate.

* If `--analyze-fks` reports nullable fallback available, re-run restore normally — Basecut handles it automatically. Note: nullable fallback is not compatible with `--on-conflict skip`; use the default conflict policy.

* Ensure referenced parent tables/rows are included in the snapshot.

* If you need a temporary bypass, use `--unsafe-disable-fk-checks` (unsafe).

* Re-run after schema alignment or adjust restore scope.

### Conflict Error (`--on-conflict error`)

```
✗ Error: duplicate key value violates unique constraint ...
```

**Solutions:**

* Use `--reset` for a clean restore target, or
* Use `--on-conflict skip` to continue and skip conflicting rows.

### Connection Failed

```
✗ Error: failed to connect to target database
  dial tcp 127.0.0.1:5432: connect: connection refused
```

**Solutions:**

* Verify the target database is running.
* Check the connection string and credentials.
* Ensure the database is accessible from your network.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Create Snapshot" icon="plus" href="/cli-reference/snapshot-create">
    Learn how to extract data from your source database
  </Card>

  <Card title="Snapshots Concept" icon="camera" href="/core-concepts/snapshots">
    Understand the anatomy and lifecycle of snapshots
  </Card>

  <Card title="Snapshot Versioning" icon="clock" href="/core-concepts/snapshot-versioning">
    Learn how tags and versions work
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/advanced/troubleshooting">
    Common issues and how to solve them
  </Card>
</CardGroup>
