Skip to Content

Database Models

Django-CFG provides Pydantic models for type-safe database configuration.

DatabaseConfig

Type-safe database connection configuration with validation.

Parameters

ParameterTypeDefaultDescription
enginestr | NoneNoneDjango database engine (auto-detected from URL scheme if not provided)
namestrrequiredDatabase name or connection string
userstr | NoneNoneDatabase user
passwordstr | NoneNoneDatabase password (hidden in repr)
hoststr"localhost"Database host
portint5432Database port (1-65535)
connect_timeoutint10Connection timeout in seconds (≥1)
sslmodestr"prefer"SSL mode for connection
optionsdict[str, Any]{}Additional database-specific options
conn_max_ageint0Maximum age of database connections in seconds (must be 0 with connection pooling)
conn_health_checksboolTrueEnable database connection health checks
appslist[str][]Django app labels that should use this database
operationslist[str]["read", "write", "migrate"]Allowed operations for this database
migrate_tostr | NoneNoneOverride database alias for migrations
routing_descriptionstr""Human-readable description of the routing rule
atomic_requestsbool | NoneNoneWrap each HTTP request in a transaction (defaults True for default, False for secondary)
test_mirrorstr | NoneNoneMirror this database to another alias during tests

Methods

MethodReturnsDescription
to_django_config()dict[str, Any]Convert to Django database configuration format

Validation

  • Port range: 1-65535
  • Timeout: ≥1 second
  • Engine: Optional — auto-detected from URL scheme when using from_url()
  • Connection string parsing: Supports postgresql://, mysql://, sqlite:/// formats

Usage Examples

SQLite Configuration

from django_cfg import DjangoConfig from django_cfg.models import DatabaseConfig class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" debug: bool = True databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.sqlite3', name='db/default.sqlite3' ) }

Generated Django settings:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'db/default.sqlite3', 'OPTIONS': { 'connect_timeout': 10, 'sslmode': 'prefer', } } }

PostgreSQL Configuration

class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" debug: bool = False databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='production_db', user='dbuser', password='secure_password', host='db.example.com', port=5432, sslmode='require', connect_timeout=30 ) }

Generated Django settings:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'production_db', 'USER': 'dbuser', 'PASSWORD': 'secure_password', 'HOST': 'db.example.com', 'PORT': 5432, 'OPTIONS': { 'connect_timeout': 30, 'sslmode': 'require', } } }

MySQL Configuration

class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" debug: bool = False databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.mysql', name='myapp_db', user='root', password='mysql_password', host='localhost', port=3306, options={ 'charset': 'utf8mb4', 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'" } ) }

Multi-Database Configuration

class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" debug: bool = False databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='users_db', user='dbuser', password='password', host='localhost' ), 'blog_db': DatabaseConfig( engine='django.db.backends.postgresql', name='blog_db', user='dbuser', password='password', host='localhost' ), 'shop_db': DatabaseConfig( engine='django.db.backends.postgresql', name='shop_db', user='dbuser', password='password', host='localhost' ) }

DatabaseRoutingRule

Type-safe database routing configuration for multi-database setups.

Parameters

ParameterTypeDefaultDescription
appslist[str]requiredList of Django apps for this rule
databasestrrequiredTarget database alias
operationslist[Literal["read", "write", "migrate"]]["read", "write", "migrate"]Allowed operations for this rule
migrate_tostr | NoneNoneOverride database for migrations
descriptionstr""Human-readable description of this rule

Methods

MethodReturnsDescription
matches_app(app_label)boolCheck if this rule matches the given app
allows_operation(operation)boolCheck if this rule allows the given operation
get_migration_database()strGet the database to use for migrations

Routing Rules Usage

Basic Routing

from django_cfg import DjangoConfig from django_cfg.models import DatabaseConfig, DatabaseRoutingRule class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" debug: bool = False databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='users_db', user='dbuser', password='password', host='localhost' ), 'blog_db': DatabaseConfig( engine='django.db.backends.postgresql', name='blog_db', user='dbuser', password='password', host='localhost' ) } database_routing: list = [ DatabaseRoutingRule( apps=['blog'], database='blog_db', description='Route blog app to blog_db' ) ]

Advanced Routing

class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" debug: bool = False databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='users_db', user='dbuser', password='password', host='localhost' ), 'blog_db': DatabaseConfig( engine='django.db.backends.postgresql', name='blog_db', user='dbuser', password='password', host='localhost' ), 'shop_db': DatabaseConfig( engine='django.db.backends.postgresql', name='shop_db', user='dbuser', password='password', host='localhost' ), 'analytics_db': DatabaseConfig( engine='django.db.backends.postgresql', name='analytics_db', user='readonly', password='password', host='analytics-server' ) } database_routing: list = [ # Blog app DatabaseRoutingRule( apps=['blog'], database='blog_db', description='Blog content in blog_db' ), # Shop app DatabaseRoutingRule( apps=['shop', 'payments'], database='shop_db', description='E-commerce in shop_db' ), # Analytics (read-only) DatabaseRoutingRule( apps=['analytics'], database='analytics_db', operations=['read'], # Read-only description='Analytics in analytics_db (read-only)' ), # Separate migrations database DatabaseRoutingRule( apps=['legacy'], database='default', migrate_to='legacy_migrations_db', description='Legacy app uses separate migrations DB' ) ]

Environment-Specific Configuration

Using Properties

class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" @property def databases(self) -> dict: if self._environment == "production": return { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='production_db', user='prod_user', password=os.getenv('DB_PASSWORD'), host='prod-db.example.com', sslmode='require' ) } else: return { 'default': DatabaseConfig( engine='django.db.backends.sqlite3', name='db/dev.sqlite3' ) }

Using YAML

# config.production.yaml databases: default: engine: "django.db.backends.postgresql" name: "production_db" user: "prod_user" password: "${DB_PASSWORD}" host: "prod-db.example.com" sslmode: "require" # config.development.yaml databases: default: engine: "django.db.backends.sqlite3" name: "db/dev.sqlite3"

Connection String Parsing

DatabaseConfig can parse connection URLs:

class MyConfig(DjangoConfig): secret_key: str = "your-secret-key" databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='postgresql://user:pass@localhost/dbname' ) }

Supported formats:

  • PostgreSQL: postgresql://user:pass@host:port/dbname
  • MySQL: mysql://user:pass@host:port/dbname
  • SQLite: sqlite:///path/to/db.sqlite3

Security Best Practices

1. Use Environment Variables

import os class MyConfig(DjangoConfig): databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name=os.getenv('DB_NAME', 'default_db'), user=os.getenv('DB_USER', 'dbuser'), password=os.getenv('DB_PASSWORD'), host=os.getenv('DB_HOST', 'localhost') ) }

2. Enable SSL in Production

class MyConfig(DjangoConfig): databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='production_db', user='prod_user', password=os.getenv('DB_PASSWORD'), host='prod-db.example.com', sslmode='require', # Enforce SSL options={ 'sslrootcert': '/path/to/ca-cert.pem' } ) }

3. Set Connection Timeouts

class MyConfig(DjangoConfig): databases: dict = { 'default': DatabaseConfig( engine='django.db.backends.postgresql', name='production_db', user='prod_user', password=os.getenv('DB_PASSWORD'), host='prod-db.example.com', connect_timeout=30, # 30 second timeout ) }

Validation

DatabaseConfig validates:

  • Port range (1-65535)
  • Timeout (≥1 second)
  • Connection string format
  • Required fields (name only; engine is optional and auto-detected from URL)

Example validation error:

# ❌ Invalid port DatabaseConfig( engine='django.db.backends.postgresql', name='mydb', port=99999 # Validation error: port must be ≤ 65535 )

See Also

Last updated on