Skip to content

Commit

Permalink
multi-database routing
Browse files Browse the repository at this point in the history
  • Loading branch information
Archmonger committed May 4, 2023
1 parent 6175d35 commit 3ce8e09
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Or, check out the **[documentation](https://archmonger.github.io/Conreq/)** for
- Customizable Core Webpages (Landing, Home, Sign In, Sign Up, Password Reset)
- Graphical Database Administration
- MySQL and SQLite Databases
- Automatic Multi-Database Routing
- Customizable Base URL
- [Interactive HTML via ReactPy](https://github.com/reactive-python/reactpy)
- [Support for Django Features](https://github.com/django/django)
Expand Down
9 changes: 8 additions & 1 deletion conreq/_core/base/management/commands/run_conreq.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ def handle(self, *args, **options):
cache.clear()

# Migrate the database
call_command("migrate", "--noinput", verbosity)
for database in settings.DATABASES.keys():
call_command(
"migrate",
"--database",
database,
"--noinput",
verbosity,
)

if not DEBUG:
# Collect static files
Expand Down
44 changes: 44 additions & 0 deletions conreq/_core/database/router.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from typing import Type

from django.apps import apps
from django.db.models import Model


class DatabaseRouter:
"""A router to control all database operations on models."""

# pylint: disable=protected-access,unused-argument

def db_for_read(self, model: Type[Model], **hints) -> None | str:
return getattr(model._meta, "db_for_read", "default")

def db_for_write(self, model: Type[Model], **hints) -> None | str:
return getattr(model._meta, "db_for_write", "default")

def allow_relation(
self, model_1: Type[Model], model_2: Type[Model], **hints
) -> None | bool:
"""Allow all relationships, unless either model has `allowed_relations`."""
rel_1: list[str] = getattr(model_1._meta, "allowed_relations", [])
rel_2: list[str] = getattr(model_2._meta, "allowed_relations", [])

if not rel_1 or rel_2:
return True

return model_2._meta.app_label in rel_1 or model_1._meta.app_label in rel_2

def allow_migrate(
self, db_name: str, app_label: str, model_name: str | None = None, **hints
) -> None | bool:
"""
Migrations only run on the `db_for_read` or `db_for_write` databases,
unless a list of `migration_databases` is specified.
"""
if model_name is None:
return None
model = apps.get_registered_model(app_label, model_name)

if hasattr(model._meta, "migration_databases"):
return db_name in model._meta.migration_databases

return db_name in (self.db_for_read(model), self.db_for_write(model))
1 change: 1 addition & 0 deletions conreq/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@
},
}
}
DATABASE_ROUTERS = ["conreq._core.database.router.DatabaseRouter"]
CACHE_SHARDS = min(WEBSERVER_WORKERS, 10)
CACHES = {
"default": {
Expand Down

0 comments on commit 3ce8e09

Please sign in to comment.