Я использую django ORM с базой данных postgres.Небольшая группа пользователей взаимодействует с ним, используя сценарии импорта и экспорта.База данных доступна только в нашей внутренней сети.Если кто-то пытается использовать базу данных, когда postgres недоступен, сценарии зависают.Прежде чем пытаться обработать какие-либо данные, я хотел бы проверить, доступны ли базы данных.
Я могу подключиться к базе данных с помощью оболочки, импортировать модель и попытаться сделать запрос:
from myapp.models import mymodel
mymodel.objects.count()
это приводит к большой задержке, но затем django вызывает OperationalError
с информативным сообщением («Не удалось подключиться к серверу: сеть недоступна ...»).
Я думалпроверить доступ к базе данных, выполнив минимальный запрос к базе данных, например:
from django.db import connection
cursor = connection.cursor()
cursor.execute("select 1")
, но это никогда не выходит за пределы строки cursor = connection.cursor()
.Нет сообщения об ошибке.
- Почему один из этих запросов вызывает ошибку, а не другой?
- Какой лучший способ проверить из сценария, доступна ли база данных?
- Как я могу гарантировать, что возникнет ошибка, если соединение не будет установлено в течение разумного (возможно, указанного пользователем) времени?
Это не веб-приложение, поэтомупромежуточное программное обеспечение а-ля Как проверить соединение с базой данных в Django? невозможно.
Редактировать
Следуя предложению @ benjaoming, яЯ сделал функцию для проверки соединения:
import socket
def test_connection():
"""Test whether the postgres database is available. Usage:
if "--offline" in sys.argv:
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings.offline'
else:
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings.standard'
from myapp.functions.connection import test_connection
test_connection()
"""
try:
s = socket.create_connection(("example.net", 5432), 5)
s.close()
except socket.timeout:
msg = """Can't detect the postgres server. If you're outside the
intranet, you might need to turn the VPN on."""
raise socket.timeout(msg)
Это, кажется, делает свое дело.