Skip to content
This repository was archived by the owner on Aug 19, 2026. It is now read-only.

fix: prevent Django tests from destroying production D1/DO data - #55

Open
Phat-pham99 wants to merge 1 commit into
G4brym:mainfrom
Phat-pham99:fix/test-db-safety
Open

Phat-pham99 wants to merge 1 commit into
G4brym:mainfrom
Phat-pham99:fix/test-db-safety

Conversation

@Phat-pham99

@Phat-pham99 Phat-pham99 commented Aug 19, 2026

Copy link
Copy Markdown

Summary

This PR fixes a critical data-loss bug where running Django tests against Cloudflare D1 or Durable Objects backends would destroy all production data.

Problem

The D1 and DO backends inherited SQLiteDatabaseCreation, which computes a test database name but does not create an isolated database for D1/DO. The D1 backend connects via CLOUDFLARE_DATABASE_ID (or binding), ignoring the NAME setting. So when Django's test runner calls _setup_test_dbmigrateflush, every query executes against the production D1 database. Since D1 has transactions disabled, each flush and truncate is permanently committed.

Solution

Override _create_test_db in CFDatabaseCreation to always raise ImproperlyConfigured, with a clear error message explaining why and how to run tests safely. No TEST setting can currently create an isolated D1 test database through django-cf, so we block unconditionally.

Safe Alternative: Separate Test Settings Module

Create a dedicated settings file for testing:

# settings/test.py
from .settings import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'test_db.sqlite3',
    }
}

Then run tests with:

python manage.py test --settings=settings.test

Or point CLOUDFLARE_DATABASE_ID to a dedicated test D1 database in your test settings.

Testing

  • Added tests/db/test_creation_safety.py with 3 tests:
    • Always raises error when _create_test_db is called
    • Still raises even when TEST['NAME'] is configured (because D1 ignores NAME)
    • Error message includes safe configuration example
  • All existing tests continue to pass (102 total)

Impact

This is a breaking change for users who were unknowingly running tests against production D1. However, this is intentional — it prevents data destruction. Users will now need to use a separate settings module for testing.

Fixes #54

Cloudflare D1 and Durable Objects backends inherited SQLite's test
database creation behavior, which does not create isolated test databases
for remote/serverless backends. This caused Django's test runner to
execute migrations and flush data directly against production databases.

- Override _create_test_db in CFDatabaseCreation to always raise
  ImproperlyConfigured when running tests against D1/DO, because no
  TEST setting can create an isolated Cloudflare test database safely
- The D1 backend connects via CLOUDFLARE_DATABASE_ID, ignoring NAME,
  so allowing tests to proceed even with TEST['NAME'] configured would
  still destroy production data
- Include helpful error message with example safe configuration

Fixes G4brym#54
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CRITICAL] django-cf D1 backend runs tests against production database, causing data loss

1 participant