我正在使用django ORM和postgres数据库。一小组用户使用导入和导出脚本与其进行交互。该数据库仅在我们的Intranet上可用。如果有人在postgres不可用时尝试使用数据库,则脚本会挂起。在尝试处理任何数据之前,我想让脚本测试数据库是否可用。
我可以使用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应用程序,因此无法使用la 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)
这似乎可以解决问题。
答案 0 :(得分:3)
您可以使用另一种方法来查明postgres服务器是否可访问:例如套接字模块 - 只需执行socket.create_connection((“server”,port))并查看它引发的异常... < / p>
答案 1 :(得分:3)
诀窍是检查django初始化时是否可以访问数据库,然后route
查询到回退数据库的所有ORM查询。
我检查数据库是否存在的一种方法是在try
.. except
块内运行ORM查询并设置一个可在routers.py
中访问的变量
from django.db import connections
conn = connections['default']
try:
c = conn.cursor() #this will take some time if error
except OperationalError:
reachable = False
else:
reachable = True
您可以将此代码放在urls.py
或routers.py
本身。
自定义路由器将检查变量是否已设置并路由到回退db
class AppRouter(object):
def db_for_read(self, model, **hints):
if reachable :
return 'actual_db'
else:
return 'fallback_db'
# define db_for_write likewise