1

두 데이터베이스에 연결하는 Django 앱이 있습니다. 내 DB 중 하나가 다른 (프로덕션) 서버에 있습니다. 앱을 개발할 때 실수로 프로덕션 서버에서 모델을 마이그레이션하지 않도록하고 싶습니다. 나의 이해는 이것이다 :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라는 라우터 클래스가 있다고 가정 내 settings.py 데이터베이스를 가정하는 것은 이것이다. 모든 라우터와 마찬가지로 해당 클래스에는 allow_migrate 메소드가 있습니다. 원격 DB는 Django auth 모델을 사용하므로 사용자 모델은 app_label 'auth'를 가지며 원격 DB는 app_label 'remoteapp'가있는 자체 모델을가집니다. 이 정보를 통해 allow_migrate 메소드에 대한 두 가지 가능성을 알 수 있습니다.

#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는 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