Python 如何在 Django 中检查与 mysql 的数据库连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32098797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how can I check database connection to mysql in django
提问by doniyor
how can I do it?
我该怎么做?
I thought, I can read something from database, but it looks too much, is there something like?:
我想,我可以从数据库中读取一些东西,但它看起来太多了,有没有类似的东西?:
settings.DATABASES['default'].check_connection()
采纳答案by Mutant
All you need to do is start a application and if its not connected it will fail. Other way you can try is on shell try following -
您需要做的就是启动一个应用程序,如果它没有连接,它就会失败。您可以尝试的其他方法是在 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
回答by LondonAppDev
I use the following Django management command called wait_for_db
:
我使用以下 Django 管理命令wait_for_db
:
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!'))
回答by radtek
I had a more complicated case where I am using mongodb behind djongo module, and RDS mysql. So not only is it multiple databases, but djongo throws an SQLDecode error instead. I also had to execute and fetch to get this working:
我有一个更复杂的案例,我在 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
I load this in my app __init__.py
, as I want it to run on startup only once and only if DEBUG is enabled. Hope it helps!
我将它加载到我的应用程序中__init__.py
,因为我希望它仅在启动时运行一次,并且仅在启用 DEBUG 时运行。希望能帮助到你!
回答by Javier Buzzi
Assuming you needed this because of docker, BUT is not limitted to docker, remember this is at the end of the day Bash, and thus works everywhere *NIX.
假设你因为 docker 而需要这个,但不限于 docker,记住这是在一天结束时 Bash,因此在任何地方都可以使用 *NIX。
You will first need to be using django-environ
, since it will make this a whole lot easier.
您首先需要使用django-environ
,因为它会使这一切变得更容易。
The DATABASE_URL
environment variable will be used inside your Django app, and here. Your settings would look like this:
该DATABASE_URL
环境变量将你的Django应用程序内使用,并在这里。您的设置如下所示:
import environ
env = environ.Env()
...
DATABASES = {
'default': env.db('DATABASE_URL'),
'other': env.db('DATABASE_OTHER_URL') # for illustration purposes
}
...
Your environment variables should look something like this: (more info 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)))
Inside your entrypoint.sh
do something like this:
在你里面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('')})['default'].ensure_connection()
except (OperationalError, DatabaseError):
sys.exit(-1)
sys.exit(0)
EOF
}
Then, lets say you want to wait for your main db [the postgres in this case], you add this inside the same entrypoint.sh
, under the database_ready
function.
然后,假设您想等待您的主数据库 [在这种情况下为 postgres],您将其添加到相同的entrypoint.sh
,database_ready
函数下。
until database_ready DATABASE_URL; do
>&2 echo "Main DB is unavailable - sleeping"
sleep 1
done
This will only continue, IF postgres is up and running. What about oracle? Same thing, under the code above, we add:
如果 postgres 启动并运行,这只会继续。甲骨文呢?同样的事情,在上面的代码下,我们添加:
until database_ready DATABASE_OTHER_URL; do
>&2 echo "Secondary DB is unavailable - sleeping"
sleep 1
done
Doing it this way will give you a couple of advantages:
这样做会给你带来几个好处:
you don't need to worry about other dependencies such as binaries and the likes.
you can switch databases and not have to worry about this breaking. (code is 100% database agnostic)
您无需担心其他依赖项,例如二进制文件等。
您可以切换数据库而不必担心这种破坏。(代码是 100% 数据库不可知的)
回答by Steve Gore
It seems Javier's answer is no longer working. He's one I put together to perform the task of checking database availability in a Docker entrypoint, assuming you have the psycopg2
library available (you're running a Django application, for instance):
似乎哈维尔的回答不再有效。他是我在 Docker 入口点执行检查数据库可用性任务的人,假设您有psycopg2
可用的库(例如,您正在运行 Django 应用程序):
function database_ready() {
python << EOF
import psycopg2
try:
db = psycopg2.connect(host="", port="", dbname="", user="", password="")
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"```