|
| 1 | +from asgiref.local import Local |
1 | 2 | from django.conf import settings |
2 | 3 |
|
3 | 4 |
|
4 | 5 | class DefaultReplicaRouter(object): |
| 6 | + """ |
| 7 | + If a model of the current thread or coroutine has used the master db, |
| 8 | + the model will also use the master in the future. |
| 9 | + This can avoid the problem that the slave database is not synchronized |
| 10 | + because a transaction is not committed. |
| 11 | + """ |
| 12 | + thread_critical = False |
| 13 | + |
| 14 | + def __init__(self): |
| 15 | + self._tracker = Local(self.thread_critical) |
5 | 16 |
|
6 | 17 | def db_for_read(self, model, **hints): |
7 | | - if 'replica' in settings.DATABASES: |
| 18 | + tracker_key = ".".join([model.__module__, model.__name__]) |
| 19 | + if hasattr(self._tracker, tracker_key): |
| 20 | + return getattr(self._tracker, tracker_key) |
| 21 | + elif 'replica' in settings.DATABASES: |
8 | 22 | return 'replica' |
9 | 23 | return 'default' |
10 | 24 |
|
11 | 25 | def db_for_write(self, model, **hints): |
| 26 | + tracker_key = ".".join([model.__module__, model.__name__]) |
| 27 | + if 'replica' in settings.DATABASES: |
| 28 | + setattr(self._tracker, tracker_key, 'default') |
12 | 29 | return 'default' |
13 | 30 |
|
14 | 31 | def allow_relation(self, obj1, obj2, **hints): |
|
0 commit comments