どうすればいいですか?
私は、データベースから何かを読むことができると思ったが、見た目が多すぎる、のようなものがありますか?:
settings.DATABASES['default'].check_connection()
必要なのは、アプリケーションを起動するだけで、接続されていない場合は失敗します。あなたが試すことができる他の方法は、シェルで次のことを試してみてください-
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
以下を使用します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!'))
ドッカーのためにこれが必要だと仮定すると、BUTはドッカーに限定されず、これは一日の終わりにあることを覚えておいてください、したがって、どこでも* 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%データベースに依存しません)
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が有効になっている場合にのみ実行するようにします。それが役に立てば幸い!
ハビエルの答えはもう機能していないようです。彼は、あなたが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"```