python / expert
Snippet
Dynamisches Multi-Tenant Datenbank-Routing über Thread-Local Kontext
Dieses Beispiel zeigt die Trennung von Mandanten (Multi-Tenancy) in Django über einen Thread-Local-Kontext und einen benutzerdefinierten Datenbank-Router. Durch das Setzen der aktiven Datenbank auf `threading.local()` werden Lese- und Schreibabfragen dynamisch an bestimmte Mandanten-Datenbanken weitergeleitet.
snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import threadingfrom django.db import models_tenant_context = threading.local()def set_current_tenant_db(db_name: str):_tenant_context.db_name = db_namedef get_current_tenant_db() -> str | None:return getattr(_tenant_context, 'db_name', None)class TenantDatabaseRouter:def db_for_read(self, model, **hints):return get_current_tenant_db() or 'default'def db_for_write(self, model, **hints):return get_current_tenant_db() or 'default'def allow_relation(self, obj1, obj2, **hints):return Truedef allow_migrate(self, db, app_label, model_name=None, **hints):return True
django
Erklärung
1
_tenant_context = threading.local()
Erstellt einen isolierten Thread-Speicher für Mandanten-Datenbank-Schlüssel zur Vermeidung von Datenlecks in Multithread-Servern.
2
class TenantDatabaseRouter:
Definiert eine eigene Router-Klasse, die in settings.DATABASE_ROUTERS zur Abfragesteuerung hinterlegt wird.
3
return get_current_tenant_db() or 'default'
Wählt dynamisch die aktive Mandanten-Datenbank aus dem Thread-Local-Status für Abfragen aus.