1

私は2つのデータベースに接続するDjangoアプリケーションを持っています。私のDBの1つは、別の(プロダクション)サーバーにあります。私は自分のアプリを開発する際に、誤ってプロダクションサーバー上のモデルを移行していないことを確かめたいと思います。私の理解では、このされています。私のsettings.pyのデータベースを仮定はこれです:Djangoはリモートデータベースの移行を防ぎます

DATABASES = { 
    'default': {}, 
    'remote_db': { 
     'NAME' : 'important_remote_db_name', 
     'ENGINE' : 'django.db.backends.mysql', 
     'USER' : 'someuser', 
     'PASSWORD': 'somepass', 
     'HOST' : 'some.production.host.com', 
     'PORT' : '3306', 
    }, 
    'myapp_db': { 
     'NAME' : 'my_app_db_name', 
     'ENGINE' : 'django.db.backends.mysql', 
     'USER' : 'localuser', 
     'PASSWORD': 'localpassword' 
    } 
} 

は今、私はまたRemoteDBRouter呼ばれるルータのクラスがあるとします。すべてのルータと同様、そのクラスにはallow_migrateというメソッドがあります。リモートDBはDjango authモデルを使用するので、Userモデルはapp_label 'auth'を持ち、リモートDBもapp_label 'remoteapp'を持つ独自のモデルを持っています。 1は、私が使用する必要があります

#OPTION 1 
def allow_migrate(self, db, app_label, model_name=None, **hints): 
    if app_label == 'auth' or app_label == 'remoteapp': 
     return db == 'remote_db' 
    return None 

#OPTION 2 
def allow_migrate(self, db, app_label, model_name=None, **hints): 
    if app_label == 'auth' or app_label == 'remoteapp': 
     return False 
    return None 

:その情報を使用すると、私は2つのallow_migrate方法の可能性を参照してください?オプション2は、app_labelがモデルがリモートDBから来たと言うモデルをマイグレーションしてはいけないというだけで簡単です。オプション1は、dbフィールドが 'remote_db'であるかどうかをチェックします(私は、 'remote_db'ではなく 'remote_db_name'をチェックする必要があると仮定します)。私はどちらを使うの?私はオプション1を使用してdbチェックが失敗した場合、メソッドはNoneを返し、Djangoコードはallow_migrateがTrueを返す次のルータクラスをチェックすることに懸念しています。

+0

リモートDBをローカルのものにしばらく毎回ダンプするのはなぜですか? –

答えて

2

RemoteDBRouterremote_dbデータベースに対して権限を持ちます。ローカルマシンからの移行を制御したくない場合はauthremoteappまたは他のアプリでは実行できません。他のデータベースは、必ずしもRemoteDBRouterによって制御されるわけではありません。あなたが書き込み操作を開発しているときに、ローカルにauthremoteappを切り替えるには、時にはたい場合

if db == 'remote_db': 
     return False 

質問があるか、あなたが予想される場合にのみアクセスのみを読んで、それらのテーブルをローカルに作成することが決して必要はありません。そのため、あなたがすることから始めます。次に、あなたが追加することができます。

if app_label == 'auth' or app_label == 'remoteapp': 
     return False 

他のデータベースのための移行がデフォルトのルータや他のルータによって制御することができます。

return None 

テスト・データベースを作成するためのテストで、より複雑であるローカルに。

DATABASES = { 
    'remote_db': { 
     ... 
     'HOST': 'some.production.host.com', 
     'USER': 'some_readonly_user', # read-only for security 
     'TEST': { 
      'HOST': 'localhost', 
      ... 
     } 
    } 
} 

オプションでは、ルータのルールにより、リモートDBへの読み取り専用アクセスをサポートすることができます。

def db_for_write(model, **hints): 
    if model._meta.app_label in ('auth', 'remoteapp'): 
     return 'myapp_db' # or maybe the db 'default' where the model doesn't exist 

例外が誤って記述している場合は、生産データを害するよりも優れています。ルータは、多くの方法でオーバーライドすることができます。 using=dbのパラメータまたは.using(db)の方法によって行われます。安全のためには、接続は読み取り専用ユーザーである必要があります。

+0

完璧、ありがとう! – Marc

+0

@Marcセキュリティについては編集済みです。 – hynekcer

関連する問題