# databases

Spiderweb is intentionally ORM-agnostic. Internally, it now uses Advanced Alchemy (built on SQLAlchemy) to persist first‑party data like sessions. You can choose one of the following approaches for your application data:

- Option 1: Use the built‑in Advanced Alchemy/SQLAlchemy setup
- Option 2: Bring your own ORM and manage its lifecycle
- Option 3: Use separate databases for Spiderweb internals and your app data

## Option 1: Use the built‑in Advanced Alchemy/SQLAlchemy setup

By default, Spiderweb will create and use a SQLite database file named `spiderweb.db` in your application directory. You can change this by passing the `db` argument to `SpiderwebRouter` as any of the following:

- A SQLAlchemy Engine instance
- A database URL string (e.g., `sqlite:///path/to.db`, `postgresql+psycopg://user:pass@host/db`)
- A filesystem path string for SQLite (e.g., `my_db.sqlite`)

Examples:

```python
from sqlalchemy import create_engine
from spiderweb import SpiderwebRouter

# Use a SQLite file by passing a path
app = SpiderwebRouter(db="my_db.sqlite")

# Or pass a SQLAlchemy engine
engine = create_engine("postgresql+psycopg://user:pass@localhost/myapp")
app = SpiderwebRouter(db=engine)

# Or pass a full URL string
app = SpiderwebRouter(db="sqlite:///./local.db")
```

## Option 2: Bring your own ORM

If you are using another ORM or data layer, create and manage it as you normally would. If you need per‑request access to a connection or session, you can attach it via custom middleware:

```python
from spiderweb.middleware import SpiderwebMiddleware
from sqlalchemy import create_engine


class SQLAlchemyMiddleware(SpiderwebMiddleware):
    engine = None

    def process_request(self, request) -> None:
        if not self.engine:
            self.engine = create_engine("sqlite:///spiderweb.db")
        request.engine = self.engine
```

Now any view that receives the incoming request object can access `request.engine` and interact with the database as needed.

> See [Writing Your Own Middleware](middleware/custom_middleware.md) for more information.

## Option 3: Use two databases

If your application requires a database not supported by SQLAlchemy or you prefer to keep concerns separated, you can run two databases: one for Spiderweb internals (sessions, etc.) and one for your application logic.

## Migrations

Migrations are handled using `alembic`, which is already installed for you. Use the management `web` commands to create and apply migrations. See the below commands for more information. 

[!ref `makemigrations` management command](/management.md#makemigrations)
[!ref `migrate` management command](/management.md#migrate)

Notes:
- If you define your own SQLAlchemy models, make sure they inherit from `spiderweb.db.Base` (or include their metadata in `target_metadata`) so Alembic can discover them.
- For multi-database setups, you can configure multiple Alembic contexts or run Alembic separately per database.
- Advanced Alchemy provides additional helpers on top of SQLAlchemy; you can use them freely alongside the guidance above.
