2

I've got two DB, I've written a router.py that correctly manage write and read, but if the read db the default is down I cannot access also the write db getting the

class TestRouter(object):

    def db_for_read(self, model, **hints):

        if model._meta.app_label == 'read_app':
            return 'default'
        if model._meta.app_label == 'write_app':
            return 'write_db'        
        return None

    def db_for_write(self, model, **hints):

        if model._meta.app_label == 'write_app':
            return 'write_db'
        return None

and in settings.py:

DATABASE_ROUTERS = ['prj.dbrouter.TestRouter', ]

this is the error:

cnn = _connect(dsn, connection_factory=connection_factory, async=async)
OperationalError: could not connect to server: Connection refused Is the server running on host "192.168.2.1" and accepting TCP/IP connections on port 5432?

is there a way to say to django to ignore failure in connection to default db?

1 Answer 1

4

Error shows that the database to which you want to connect is not accepting request or listening from host "192.168.2.1".

In postgresql.conf file, change listen_addresses = '*'

Lemme elaborate what exactly you should do,

  1. Add the database information in your settings.py and also information about the routers.py :

settings.py

DATABASES = {
    'default': {},
    'master': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': 5432,
    },
    'slave': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': 5432,
    }
}
SLAVE_DATABASES = ['slave']

DATABASE_ROUTERS = ['path.to.your.routers.MasterSlaveRouter']
  1. Create the routers.py which will handle switching the read and write request among the database mentioned in settings :

routers.py

from django.conf import settings
import socket


def test_connection_to_db(database_name):
    try:
        db_definition = getattr(settings, 'DATABASES')[database_name]
        s = socket.create_connection(
            (db_definition['HOST'], db_definition['PORT']), 5)
        s.close()
        return True
    except:
        return False


class MasterSlaveRouter(object):
    def db_for_read(self, model, **hints):
        """
        Reads go to a randomly-chosen slave.
        """
        if test_connection_to_db('master'):
            return 'master'
        return 'slave'

    def db_for_write(self, model, **hints):
        """
        Writes always go to master.
        """
        if test_connection_to_db('master'):
            return 'master'
        return 'slave'

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

    def allow_migrate(self, db, model):
        """
        All non-auth models end up in this pool.
        """
        return True

So now if your master is down and slave is up. Request will be transferred accordingly and vice-versa. Make sure any one database is up.

HTH! :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.