하나의 테이블“django_migrations”만으로 Django에서 여러 데이터베이스를 사용하십시오.


11

Django의 프로젝트의 경우 기본 데이터베이스 와 원격 데이터베이스 두 가지를 사용해야합니다 . 나는 만들었고 routers.py모든 것이 잘 작동합니다.

원격 데이터베이스에서 테이블을 작성해야하는 요구 사항이 있었고 마이그레이션을 작성하고 실행했으며 테이블 django_migrations이 작성되었습니다. django_migrations기본 데이터베이스에 하나의 테이블 만 갖고 싶습니다 .

관련 부분은 다음 routers.py과 같습니다.

class MyRouter(object):
     # ...
     def allow_migrate(self, db, app_label, model_name=None, **hints):
         if app_label == 'my_app':
             return db == 'remote'
         return None

다음과 같이 마이그레이션을 실행합니다.

python manage.py migrate my_app --database=remote

이제 내가 할 때 :

python manage.py runserver

다음과 같은 경고가 나타납니다.

적용되지 않은 마이그레이션이 1 개 있습니다. 앱 마이그레이션 my_app를 적용 할 때까지 프로젝트가 제대로 작동하지 않을 수 있습니다.
'python manage.py migrate'를 실행하여 적용하십시오.

에 대한 테이블 my_appremote데이터베이스에 작성되고 데이터베이스 django_migrations내부 remote에 마이그레이션이 적용됨으로 표시됩니다.

편집 :
Django가 하나의 테이블 만 사용하도록 django_migrations하지만 어떻게 다른 데이터베이스에 마이그레이션을 적용합니까?

경고가 발생하지 않도록 다른 데이터베이스에서 마이그레이션을 적용하는 방법은 무엇입니까?


1
'my_app'이 아닌 다른 앱의 경우 allow_migrate가 None을 반환합니다. 다른 검사를하고 싶습니까? 라우터에서 내가 이해 한 바에 따르면 'my_app'는 '원격'데이터베이스를 사용하고 다른 모든 앱은 '기본'데이터베이스를 사용합니까?
Martin Taleski

@cezar 당신은 거의 불가능한 것을 요구합니다. django_migrations테이블 을 공유 하려면 마이그레이션 대상이있는 행 defaultremotedb 를 구분해야합니다 . 이것은 장고 내부에서 꽤 깊습니다. 마이그레이션 코드를 크게 다시 작성해야 할 수도 있습니다.
Kamil Niski

@KamilNiski 의견을 보내 주셔서 감사합니다. 나는 그 질문을 다시 말할 것이다.
cezar

이 문제 는 관련 있을 수 있습니다.
케빈 크리스토퍼 헨리

답변:


2

내 질문에 대한 의견 덕분에 나는 약간의 연구를했으며 다음과 같은 결과를 얻었습니다.

여러 데이터베이스를 사용 django_migrations하면 마이그레이션이 사용될 때 테이블이 작성 됩니다. Kamil Niski의 설명에 django_migrations따르면 한 테이블에만 마이그레이션을 기록 할 수있는 옵션이 없습니다 . 이것은 파일을 읽은 후에 분명합니다 .django/db/migrations/recorder.py

프로젝트 내부에 프로젝트 foo와 앱이 포함 된 예제를 설명하겠습니다 bar. 이 앱 bar에는 하나의 모델 만 있습니다 Baz.

우리는 프로젝트를 만듭니다 :

django-admin startproject foo

이제 메인 프로젝트 디렉토리 안에 이러한 내용이 있습니다 :

- foo
- manage.py

프로젝트 디렉토리 안에 모든 앱을 그룹화하는 습관이 있습니다.

mkdir foo/bar
python manage.py bar foo/bar

파일에서 foo/settings.py우리는이 예제의 목적을 위해 두 개의 다른 데이터베이스를 사용하도록 설정을 조정합니다 sqlite3.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db1.sqlite3'),
    },
    'remote': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
    }
}

이제 마이그레이션을 실행합니다 :

python manage.py migrate --database=default

--database=default지정하지 않으면 Django가 기본 데이터베이스를 사용하므로 모든 마이그레이션을 실행합니다.이 부분 은 선택 사항입니다.

수행 할 작업 : 
  모든 마이그레이션 적용 : admin, auth, contenttypes, sessions
 마이그레이션 실행 :
  contenttypes 적용 중 0001_initial ... 확인
  auth.0001_initial 적용 중 ... 확인
  admin.0001_initial 적용 중 ... 확인
  admin.0002_logentry_remove_auto_add 적용 중 ... 확인
  admin.0003_logentry_add_action_flag_choices 적용 중 ... 확인
  contenttypes 적용 중 ... 0002_remove_content_type_name ... 확인
  auth.0002_alter_permission_name_max_length 적용 중 ... 확인
  auth.0003_alter_user_email_max_length 적용 중 ... 확인
  auth.0004_alter_user_username_opts 적용 중 ... 확인
  auth.0005_alter_user_last_login_null 적용 중 ... 확인
  auth.0006_require_contenttypes_0002 적용 중 ... 확인
  auth.0007_alter_validators_add_error_messages 적용 중 ... 확인
  auth.0008_alter_user_username_max_length 적용 중 ... 확인
  auth.0009_alter_user_last_name_max_length 적용 중 ... 확인
  auth.0010_alter_group_name_max_length 적용 중 ... 확인
  auth.0011_update_proxy_permissions 적용 중 ... 확인
  세션 적용 중 0001_initial ... OK

Django는 모든 마이그레이션을 기본 데이터베이스에 적용했습니다.

1 개의 콘텐츠 유형 0001_initial 2019-11-13 16 : 51 : 04.767382
2 권 0001_ 초기 2019-11-13 16 : 51 : 04.792245
3 관리자 0001_ 초기 2019-11-13 16 : 51 : 04.827454
4 관리자 0002_logentr 2019-11-13 16 : 51 : 04.846627
5 관리자 0003_logentr 2019-11-13 16 : 51 : 04.864458
6 개의 contenttypes 0002_remove_ 2019-11-13 16 : 51 : 04.892220
7 권 0002_alter_p 2019-11-13 16 : 51 : 04.906449
8 인증 0003_alter_u 2019-11-13 16 : 51 : 04.923902
9 인증 0004_alter_u 2019-11-13 16 : 51 : 04.941707
10 auth 0005_alter_u 2019-11-13 16 : 51 : 04.958371
11 인증 0006_ 필요 2019-11-13 16 : 51 : 04.965527
12 인증 0007_alter_v 2019-11-13 16 : 51 : 04.981532
13 인증 0008_alter_u 2019-11-13 16 : 51 : 05.004149
14 인증 0009_alter_u 2019-11-13 16 : 51 : 05.019705
15 권 0010_alter_g 2019-11-13 16 : 51 : 05.037023
16 권 0011_update_ 2019-11-13 16 : 51 : 05.054449
17 회 0001_ 초기 2019-11-13 16 : 51 : 05.063868

이제 모델을 만듭니다 Baz:

models.py:

from django.db import models

class Baz(models.Model):
    name = models.CharField(max_length=255, unique=True)

barINSTALLED_APPS( foo/settings.py)에 등록하고 마이그레이션을 만듭니다.

python manage.py makemigrations bar

마이그레이션을 실행하기 전에 앱 routers.py내부에서 생성 bar합니다.

BarRouter (객체) 클래스 :
    데프 db_for_read (자체, 모델, ** 힌트) :
        model._meta.app_label == 'bar'인 경우 :
            '원격'을 반환
        반환 없음

    데프 db_for_write (자체, 모델, ** 힌트) :
        model._meta.app_label == 'bar'인 경우 :
            '원격'을 반환
        반환 없음

    데프 allow_relation (자체, obj1, obj2, ** 힌트) :
        반환 없음

    def allow_migrate (자체, db, app_label, model_name = 없음, ** 힌트) :
        app_label == 'bar'인 경우 :
            리턴 db == '원격'
        db == '원격'인 경우 :
            False를 반환
        반환 없음

그리고 그것을 등록하십시오 foo/settings.py:

DATABASE_ROUTERS = ['foo.bar.routers.BarRouter']

이제 순진한 접근 방식은 데이터베이스 bar로 마이그레이션을 실행하는 것입니다 remote.

python manage.py migrate bar --database=remote
수행 할 작업 : 
  모든 마이그레이션 적용 : bar
 마이그레이션 실행 :
  bar.0001_initial을 적용하는 중 ... 확인

마이그레이션이 remote데이터베이스 에 적용되었습니다 .

1 바 0001_ 초기 2019-11-13 17 : 32 : 39.701784

우리가 달릴 때 :

python manage.py runserver

다음과 같은 경고가 발생합니다.

적용되지 않은 마이그레이션이 1 개 있습니다. 앱 ::에 대한 마이그레이션을 적용 할 때까지 프로젝트가 제대로 작동하지 않을 수 있습니다.
'python manage.py migrate'를 실행하여 적용하십시오.

그래도 모든 것이 잘 작동하는 것 같습니다. 그러나이 경고가 만족스럽지 않습니다.

답변 에서 제안한대로 각 데이터베이스에 대해 모든 마이그레이션을 실행하는 것이 올바른 방법입니다 .

다음과 같이 보일 것입니다 :

python manage.py migrate --database=default
python manage.py migrate --database=remote

다음에 대한 마이그레이션을 생성 한 후 bar:

python manage.py migrate bar --database=default
python manage.py migrate bar --database=remote

라우터는 테이블 bar_bazremote데이터베이스 에서만 생성 되도록 관리 하지만 Django는 마이그레이션이 두 데이터베이스 모두에 적용된 것으로 표시합니다. 에 대한 또한, 테이블 auth, admin, sessions, 등 만 생성됩니다 default에 명시된 바와 같이, 데이터베이스 routers.py. 표 django_migrations에서remote데이터베이스 이러한 마이그레이션에 대한 레코드도 있습니다.

그것은 오랫동안 읽었지만 공식 문서의 문제를 철저히 설명하지 않았기 때문에 이것에 약간의 빛을 비추기를 바랍니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.