我正在使用Django ORM与Postgres数据库。一小组用户使用导入和导出脚本与其交互。该数据库仅在我们的内部网络上可用。如果Postgres不可用,某些人尝试使用数据库时这些脚本会挂起。我想让这些脚本在尝试处理任何数据之前测试数据库是否可用。
我可以使用shell连接到数据库,导入模型并尝试进行查询:
这会导致长时间的延迟,但随后Django会抛出一个带有信息的
我考虑通过对数据库进行最小查询来测试数据库访问,例如:
但是代码永远无法执行到
这似乎可以解决问题。
我可以使用shell连接到数据库,导入模型并尝试进行查询:
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()
这一行,也没有错误信息。
- 为什么其中一个查询会引发错误,而另一个则不会?
- 从脚本中测试数据库是否可用的最佳方法是什么?
- 如何确保如果连接在合理的时间内(可能是用户指定的)未成功,则会引发错误?
这不是一个Web应用程序,因此像How do I test a database connection in 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)
这似乎可以解决问题。