我该怎么办?
我想,我可以从数据库中读取一些内容,但它看起来太多了,有什么类似的吗?:
settings.DATABASES['default'].check_connection()
答案 0 :(得分:21)
您需要做的就是启动一个应用程序,如果它没有连接,它将失败。您可以尝试的其他方式是在shell上尝试以下 -
from django.db import connections
from django.db.utils import OperationalError
db_conn = connections['default']
try:
c = db_conn.cursor()
except OperationalError:
connected = False
else:
connected = True
答案 1 :(得分:4)
这是一个老问题,但需要更新的答案
python manage.py check --database default
如果您不使用默认值,或者您想测试设置中列出的其他数据库,只需将其命名即可。
它从 3.1 + 版本开始可用
答案 2 :(得分:1)
我使用以下名为wait_for_db
的Django管理命令:
import time
from django.db import connection
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand
class Command(BaseCommand):
"""Django command that waits for database to be available"""
def handle(self, *args, **options):
"""Handle the command"""
self.stdout.write('Waiting for database...')
db_conn = None
while not db_conn:
try:
connection.ensure_connection()
db_conn = True
except OperationalError:
self.stdout.write('Database unavailable, waiting 1 second...')
time.sleep(1)
self.stdout.write(self.style.SUCCESS('Database available!'))
答案 3 :(得分:1)
假定您由于docker而需要此功能,但BUT不仅限于docker,请记住这是在Bash结束时,因此可以在所有* NIX上使用。
您首先需要使用django-environ
,因为这样做会更加容易。
DATABASE_URL
环境变量将在Django应用中以及此处使用。您的设置如下所示:
import environ
env = environ.Env()
...
DATABASES = {
'default': env.db('DATABASE_URL'),
'other': env.db('DATABASE_OTHER_URL') # for illustration purposes
}
...
您的环境变量应如下所示:(更多信息here)
# This works with ALL the databases django supports ie (mysql/mssql/sqlite/...)
DATABASE_URL=postgres://user:pass@name_of_box:5432/database_name
DATABASE_OTHER_URL=oracle://user:pass@/(description=(address=(host=name_of_box)(protocol=tcp)(port=1521))(connect_data=(SERVICE_NAME=EX)))
在您的entrypoint.sh
内执行以下操作:
function database_ready() {
# You need to pass a single argument called "evironment_dsn"
python << EOF
import sys
import environ
from django.db.utils import ConnectionHandler, OperationalError
env = environ.Env()
try:
ConnectionHandler(databases={'default': env.db('$1')})['default'].ensure_connection()
except (OperationalError, DatabaseError):
sys.exit(-1)
sys.exit(0)
EOF
}
然后,假设您要等待主数据库(在这种情况下为postgres),则将其添加到entrypoint.sh
函数下的同一database_ready
内。
until database_ready DATABASE_URL; do
>&2 echo "Main DB is unavailable - sleeping"
sleep 1
done
只有在postgres已启动并正在运行时,此操作才会继续。甲骨文呢?同样,在上面的代码下,我们添加:
until database_ready DATABASE_OTHER_URL; do
>&2 echo "Secondary DB is unavailable - sleeping"
sleep 1
done
以这种方式进行操作将为您带来一些好处:
您无需担心二进制文件之类的其他依赖项。
您可以切换数据库,而不必担心这种中断。 (代码是100%与数据库无关的)
答案 4 :(得分:1)
运行外壳
python manage.py shell
执行此脚本
import django
print(django.db.connection.ensure_connection())
如果打印None
表示一切正常,否则如果您的数据库连接发生问题,它将抛出错误
答案 5 :(得分:1)
import time
from django.core.management.base import BaseCommand
from django.db import connection
from django.db.utils import OperationalError
from django.utils.translation import ngettext
class Command(BaseCommand):
help = "Checks database connection"
def add_arguments(self, parser):
parser.add_argument(
"--seconds",
nargs="?",
type=int,
const=1,
help="Number of seconds to wait before retrying",
default=1,
)
def handle(self, *args, **options):
wait = options["seconds"]
while True:
try:
connection.ensure_connection()
break
except OperationalError:
plural_time = ngettext("second", "seconds", wait)
self.stdout.write(
self.style.WARNING(
f"Database unavailable, retrying after {wait} {plural_time}!"
)
)
time.sleep(wait)
self.stdout.write(self.style.SUCCESS("Database connections successful"))
python manage.py waitdb --seconds 5
python manage.py waitdb # defaults to 1 seconds
答案 6 :(得分:0)
我有一个更复杂的情况,我在djongo模块和RDS mysql后面使用mongodb。因此,不仅是多个数据库,而且djongo还会引发SQLDecode错误。我还必须执行并获取才能正常工作:
from django.conf import settings
if settings.DEBUG:
# Quick database check here
from django.db import connections
from django.db.utils import OperationalError
dbs = settings.DATABASES.keys()
for db in dbs:
db_conn = connections[db] # i.e. default
try:
c = db_conn.cursor()
c.execute("""SELECT "non_existent_table"."id" FROM "non_existent_table" LIMIT 1""")
c.fetchone()
print("Database '{}' connection ok.".format(db)) # This case is for djongo decoding sql ok
except OperationalError as e:
if 'no such table' in str(e):
print("Database '{}' connection ok.".format(db)) # This is ok, db is present
else:
raise # Another type of op error
except Exception: # djongo sql decode error
print("ERROR: Database {} looks to be down.".format(db))
raise
我将其加载到我的应用__init__.py
中,因为我希望它仅在启用DEBUG的情况下在启动时运行一次。希望对您有帮助!
答案 7 :(得分:0)
似乎哈维尔的答案不再起作用。假设您有psycopg2
库可用(例如,您正在运行Django应用程序),他就是我一起在Docker入口点中执行检查数据库可用性的任务的人:
function database_ready() {
python << EOF
import psycopg2
try:
db = psycopg2.connect(host="$1", port="$2", dbname="$3", user="$4", password="$5")
except:
exit(1)
exit(0)
EOF
}
until database_ready $DATABASE_HOST $DATABASE_PORT $DATABASE_NAME $DATABASE_USER $DATABASE_PASSWORD; do
>&2 echo "Database is unavailable at $DATABASE_HOST:$DATABASE_PORT/$DATABASE_NAME - sleeping..."
sleep 1
done
echo "Database is ready - $DATABASE_HOST:$DATABASE_PORT/$DATABASE_NAME"```