Django Db routing
<p>I am trying to run my Django application with two db's (1 master, 1 read replica). My problem is if I try to read right after a write the code explodes. For example:</p>

<ul>
<li>p = Product.objects.create()</li>
<li><ol>
<li>Product.objects.get(id=p.id)</li>
</ol></li>
</ul>

<p>OR</p>

<ul>
<li><ol start="2">
<li>If user is redirected to Product's
details page</li>
</ol></li>
</ul>

<p>The code runs way faster than the read replica. And if the read operation uses the replica the code crashes, because it didn't update in time. </p>

<p>Is there any way to avoid this? For example, the db to read being chosen by request instead of by operation?</p>

<p>My Router is identical to Django's documentation:</p>

<pre><code>import random

class PrimaryReplicaRouter(object):
    def db_for_read(self, model, **hints):
        """
        Reads go to a randomly-chosen replica.
        """
        return random.choice(['replica1', 'replica2'])

    def db_for_write(self, model, **hints):
        """
        Writes always go to primary.
        """
        return 'primary'

    def allow_relation(self, obj1, obj2, **hints):
        """
        Relations between objects are allowed if both objects are
        in the primary/replica pool.
        """
        db_list = ('primary', 'replica1', 'replica2')
        if obj1._state.db in db_list and obj2._state.db in db_list:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        All non-auth models end up in this pool.
        """
        return True
</code></pre>

<p>Depending on the size of the data and the application I'd tackle this with either of the following methods:</p>

<ol>
<li>Database pinning:</li>
</ol>

<p>Extend your database router to allow pinning functions to specific databases. For example:</p>

<pre><code>from customrouter.pinning import use_master

@use_master
def save_and_fetch_foo():
    ...
</code></pre>

<p>A good example of that can be seen in <a href="https://github.com/jbalogh/django-multidb-router/blob/master/multidb/pinning.py" rel="nofollow">django-multidb-router</a>.
Of cource you could just use this package as well.</p>

<ol start="2">
<li><p>Use a <a href="https://docs.djangoproject.com/en/1.10/topics/db/multi-db/#using-managers-with-multiple-databases" rel="nofollow">model manager to route queries to specific databases</a>. </p>

<pre><code>class MyManager(models.Manager):
    def get_queryset(self):
        qs = CustomQuerySet(self.model)
        if self._db is not None:
            qs = qs.using(self._db)
        return qs
</code></pre></li>
<li><p>Write a middleware that'd route your requests to master/slave automatically.
Basically same as the pinning method but you wouldn't specify when to run <code>GET</code> requests against master.</p></li>
</ol>

python django