Как я могу проверить подключение базы данных к mysql в django

как я могу это сделать?

Я думал, что я могу что-то прочитать из базы данных, но это выглядит слишком много, есть что-то вроде?:

settings.DATABASES['default'].check_connection()

Ответ 1

Все, что вам нужно сделать, это запустить приложение, и если он не подключен, он не будет работать. Другой способ, который вы можете попробовать, - включить оболочку из командной строки -

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

Ответ 2

Я использую следующую команду управления 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!'))

Ответ 3

Предполагая, что вам это нужно из-за докера, НО не ограничивается докером, помните, что это в конце дня 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
}

...

Переменные вашей среды должны выглядеть примерно так: (подробнее здесь)

# This works with ALL the databases django supports ie (mysql/mssql/sqlite/...)
DATABASE_URL=postgres://user:[email protected]_of_box:5432/database_name
DATABASE_OTHER_URL=oracle://user:[email protected]/(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
}

Затем, допустим, вы хотите дождаться своей основной database_ready [в данном случае 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

Делая это таким образом, вы получите пару преимуществ:

  1. вам не нужно беспокоиться о других зависимостях, таких как двоичные файлы и тому подобное.

  2. Вы можете переключать базы данных и не беспокоиться об этом нарушении. (код не зависит от базы данных)

Ответ 4

У меня был более сложный случай, когда я использую mongodb за модулем djongo и RDS mysql. Так что это не только несколько баз данных, но и 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. Надеюсь, поможет!

Ответ 5

Кажется, ответ Хавьера больше не работает. Тот, который я собрал, чтобы выполнить задачу проверки доступности базы данных в точке входа Docker, предполагая, что у вас есть библиотека psycopg2 (например, вы запускаете приложение Django):

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"'''