# Database Testing

Database access control, transaction management, and database setup fixtures for Django testing with pytest. These fixtures handle test database creation, transaction rollback, sequence reset, and parallel testing isolation.

## Capabilities

### Basic Database Access

Enable database access for tests with automatic transaction rollback after each test.

```python { .api }
def db() -> None:
    """
    Enable database access for test with transaction rollback.
    
    Automatically rolls back any database changes after test completion.
    Use this fixture when you need basic database access without 
    transaction testing requirements.
    """
```

Usage example:
```python
@pytest.mark.django_db
def test_model_creation(db):
    from myapp.models import MyModel
    obj = MyModel.objects.create(name="test")
    assert obj.name == "test"
    # Database changes automatically rolled back
```

### Transactional Database Access

Enable database access with transaction support for testing transaction-related functionality.

```python { .api }
def transactional_db() -> None:
    """
    Enable database access with transaction support.
    
    Unlike the db fixture, this allows testing of transaction.atomic(),
    on_commit callbacks, and other transaction-related Django features.
    Database changes are still cleaned up after the test.
    """
```

Usage example:
```python
@pytest.mark.django_db(transaction=True)
def test_transaction_atomic(transactional_db):
    from django.db import transaction
    from myapp.models import MyModel
    
    with transaction.atomic():
        MyModel.objects.create(name="test1")
        # Test transaction behavior
```

### Database Setup

Session-scoped fixture for database setup and configuration.

```python { .api }
def django_db_setup() -> None:
    """
    Set up Django test databases for the test session.
    
    Session-scoped fixture that creates test databases and applies
    migrations. Automatically handles database cleanup at session end.
    Called automatically when database fixtures are used.
    """
```

### Database Settings Modification

Control database configuration for parallel and distributed testing.

```python { .api }
def django_db_modify_db_settings() -> None:
    """
    Modify database settings for parallel test execution.
    
    Session-scoped fixture that automatically adds suffixes to database
    names for tox parallel execution and pytest-xdist worker processes.
    """

def django_db_modify_db_settings_parallel_suffix(
    django_db_modify_db_settings_tox_suffix: None,
    django_db_modify_db_settings_xdist_suffix: None
) -> None:
    """
    Apply parallel testing database name suffixes.
    
    Combines tox and xdist suffixes for database isolation in
    parallel test execution environments.
    """

def django_db_modify_db_settings_tox_suffix() -> None:
    """
    Add tox environment suffix to database names.
    
    Session-scoped fixture that adds TOX_PARALLEL_ENV suffix
    to test database names for tox parallel execution isolation.
    """

def django_db_modify_db_settings_xdist_suffix(request: pytest.FixtureRequest) -> None:
    """
    Add pytest-xdist worker suffix to database names.
    
    Session-scoped fixture that adds worker ID suffix (gw0, gw1, etc.)
    to test database names for pytest-xdist parallel execution isolation.
    """
```

### Sequence Reset

Reset database sequences after tests that insert data with explicit primary keys.

```python { .api }
def django_db_reset_sequences() -> None:
    """
    Reset database sequences after test completion.
    
    Use when tests create objects with explicit primary key values,
    ensuring sequences are properly reset for subsequent tests.
    Only works with databases that support sequences (PostgreSQL, Oracle).
    """
```

Usage example:
```python
@pytest.mark.django_db(reset_sequences=True)
def test_with_explicit_pk(django_db_reset_sequences):
    from myapp.models import MyModel
    MyModel.objects.create(id=100, name="test")
    # Sequences automatically reset after test
```

### Serialized Rollback

Enable serialized rollback for tests that require specific database state.

```python { .api }
def django_db_serialized_rollback() -> None:
    """
    Enable serialized rollback for database state preservation.
    
    Serializes database state before test and restores it after,
    instead of using transaction rollback. Useful for tests that
    require specific database state or work with multiple databases.
    """
```

Usage example:
```python
@pytest.mark.django_db(serialized_rollback=True)
def test_with_serialized_rollback(django_db_serialized_rollback):
    # Test with preserved database state
    pass
```

### Migration Control

Control whether Django migrations are used during test database setup.

```python { .api }
def django_db_use_migrations(request: pytest.FixtureRequest) -> bool:
    """
    Control migration usage during test database setup.
    
    Session-scoped fixture that determines whether Django migrations
    are applied during test database creation. Can be controlled via
    --migrations/--nomigrations command line options.
    
    Returns:
        bool: True if migrations should be used, False otherwise
    """
```

### Database Persistence Control

Control test database creation and persistence across test runs.

```python { .api }
def django_db_keepdb(request: pytest.FixtureRequest) -> bool:
    """
    Control database persistence across test runs.
    
    Session-scoped fixture that determines whether the test database
    should be preserved after test completion. Controlled via
    --reuse-db command line option.
    
    Returns:
        bool: True if database should be kept, False otherwise
    """

def django_db_createdb(request: pytest.FixtureRequest) -> bool:
    """
    Control test database creation behavior.
    
    Session-scoped fixture that determines whether the test database
    should be recreated even if it exists. Controlled via
    --create-db command line option.
    
    Returns:
        bool: True if database should be recreated, False otherwise
    """
```

## Database Configuration Types

```python { .api }
from typing import Optional, Union, List, Literal, Tuple, Iterable

# Database selection types
DatabasesType = Optional[Union[Literal["__all__"], Iterable[str]]]
AvailableAppsType = Optional[List[str]]

# Internal database configuration tuple
DatabaseConfigTuple = Tuple[
    bool,  # transaction
    bool,  # reset_sequences
    DatabasesType,  # databases
    bool,  # serialized_rollback
    AvailableAppsType  # available_apps
]
```