I have a second database in my Django application. However, I need a VPN to connect to it. If my VPN is not enabled psycop2
will throw an operational error back at me. However, I would like the ability for that database to fail silently and fallback to the default database in case the connection is refused. Is there a way to do this? I cant seem to find a default way and it seems like a very basic functionality to have.
I have tried to implement something through routers suggested in stackoverflow before, but at startup my application will simply say OperationalError: Connection Refused
and then crash the rest of the startup procedure.
class OVIRouter:
"""
A router that takes all of the reads, writes and changes to the OVIDevice model
(also known as "ovidevice" once the model is translated to SQL), and sends them
to the OVI database (The database configured in settings.py through the "ovi_db"
entry in the DATABASES constant).
"""
db_name = 'ovi_db'
def db_for_read(self, model: Model, **hints: Any) -> Optional[str]:
"""
Attempts to read the OVIDevice model go to the OVI device database. If the
connection to the OVI device database fails, the default database is used.
"""
if test_connection_to_db(self.db_name):
if model._meta.model_name == "ovidevice":
return self.db_name
return None
else:
return 'default'
def db_for_write(self, model: Model, **hints: Any) -> Optional[str]:
"""
Attempts to write the OVIDevice model go to the OVI device database. If the
connection to the OVI device database fails, the default database is used.
"""
if test_connection_to_db(self.db_name):
if model._meta.model_name == "ovidevice":
return 'ovi_db'
return None
else:
return 'default'
def allow_relation(self, obj1: Model, obj2: Model, **hints: Any) -> Optional[bool]:
"""
Allow relations if the OVIDevice model is involved.
"""
if (
obj1._meta.model_name == "ovidevice" or
obj2._meta.model_name == "ovidevice"
):
return True
return None
def allow_migrate(
self,
db: Model,
app_label: str,
model_name: Optional[str] = None,
**hints: Any
) -> Optional[str]:
"""
Make sure the ovidevice model only appears in the OVI device database.
If the connection to the OVI device database fails, the default database
will be used.
"""
if test_connection_to_db(self.db_name):
if model_name == "ovidevice":
return 'ovi_db'
return None
else:
return 'default'
Am I overthinking this? Cause I think this solution would work if the application is already working, but when you try to start the application, psycop2 will always try to connect, making my startup crash.
I know its tempting to say "just dont have the external database go down", but unfortunately its an external database over which I don't have any control. I just want to make my application more resilient. Thank you!