2017-11-01 14 views
1

배경 내가 여러 데이터베이스와 장고를 사용하고

: 나는 포스트 그레스 데이터베이스와 (I 천천히 포스트 그레스까지 변환하고있어 기존의 데이터로 채워) MySQL 데이터베이스를 가지고 있습니다.장고 'geo_db_type'AttributeError

나는 최근에 geoDjango (django.contrib.gis 형태로)를 가져 왔으며 lat/lng 정보를 포인트로 저장하기위한 postgis 확장자를 사용했습니다. 응용 프로그램 자체가 정상적으로 작동하는 것 같습니다. 나는 mysql 데이터베이스와 postgres 데이터베이스로부터 정보를 접근 할 수있다. 나는 새로운 포인트 필드를 활용할 수도 있는데, 이는 'gis'물건이 작동하고 구성된다는 것을 의미합니다.

문제

테스트를 실행하려고하면 문제가 발생합니다. 나는 다음과 같은 오류가 발생합니다 :

AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type' 

내가 먼저 test_db를 위해 Postgress 데이터베이스가 존재하고 삭제하고 다시해야한다는 프롬프트를 얻을 수 있기 때문에이 MySQL 데이터베이스에 발생하는 믿습니다. 나는 'yes'라고 입력하면, test_mysql 데이터베이스에 대한 동일한 프롬프트를 보여줍니다. '예'라고 대답하면 오류가 발생합니다.

내 기존 앱의 모델은 새로운 필드를 사용하지 않습니다. 가져 오기는 django.db입니다. 그래서 왜 테스트에서 mysql 데이터베이스에서 지형 공간 연산이 필요하다고 생각하는지 알 수 없습니다. 내가

1) MySQL 데이터베이스이 실제로 작동

을 주석을 시도했다

; 테스트가 잘 실행됩니다. 그러나, 이것은 MySQL의 데이터베이스 엔진을 변경

2) 나는 다른 가져 오기 '를 django.contrib.gis.db.backends.mysql'

를 사용하는 ... 분명한 이유에 대한 좋은 해결책이 아니다 오류가 발생했습니다.

django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes') 

나는 이것이 기존 모델의 어딘가에있는 복합 키 때문이라고 생각합니다. 이것은 실제로 문제가되어서는 안된다고 생각합니다. 왜냐하면 실제로 MariaDB 10.0.31을 백그라운드에서 실행하고 있기 때문입니다. 또한 django.db.backends.mysql은 그것에 대해 불평하지 않습니다. 그래서 django.contrib.gis.db.backends.mysql이 약간 구식인지 (MySQL은 어쨌든 한정된 공간 지원을 갖고있는 것 같기 때문에) 궁금합니다.

테스트 데이터베이스가 불평하지만 응용 프로그램이 정상적으로 정상적으로 작동하는 이유를 알 수 없습니다.

제공 할 수있는 도움에 미리 감사드립니다. 나는 완전히 엉망이다.내 데이터베이스 구성은 다음과 같다 정보

지원

:

DATABASES = { 
    'default': { 
     'ENGINE': 'django.contrib.gis.db.backends.postgis', 
     'NAME': os.environ.get('PG_DB_NAME'), 
     'USER': os.environ.get('PG_DB_USER'), 
     'PASSWORD': os.environ.get('PG_DB_PASS'), 
     'HOST': os.environ.get('PG_DB_HOST'), 
     'PORT': '', 
    }, 
    'legacy': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': os.environ.get('MY_DB_NAME'), 
     'USER': os.environ.get('MY_DB_USER'), 
     'PASSWORD': os.environ.get('MY_DB_PASS'), 
     'HOST': os.environ.get('MY_DB_HOST'), 
     'PORT': '', 
    }, 
} 

나는 데이터베이스 라우터가 :

class LegacyRouter(object): 
    def db_for_read(self, model, **hints): 

     if model._meta.app_label == 'legacy': 
      return 'legacy' 
     return 'default' 

편집 : 해키 해결

그래서, 일부 시험 후 그리고 오류, 나는 하나의 게시물을 사용하여이 문제를 해결할 수 있다는 것을 발견했다. 테스트 용 gresql 데이터베이스. 두 번째 설정 파일을 추가하고 테스트 할 때이를 참조하여이 작업을 수행했습니다. 같은 시험 시간에 호출되는

from .settings import * 

DATABASES = { 
    'default': { 
     'ENGINE': 'django.contrib.gis.db.backends.postgis', 
     'NAME': os.environ.get('TEST_DB_NAME'), 
     'USER': os.environ.get('TEST_DB_USER'), 
     'PASSWORD': os.environ.get('TEST_DB_PASS'), 
     'HOST': os.environ.get('TEST_DB_HOST'), 
    }, 
} 

DATABASE_ROUTERS = [] 

: 내 기존 데이터에 대한 아무것도 데이터베이스 관련이 있기 때문에

python manage.py test --settings=<module>.test-settings 

이것은 나를 위해 작동, 그래서에 포스트 그레스를 사용할 수없는 이유가 없다 테스트. 희망적으로 이것은 다른 사람을 돕는다.

수정 : 수정

데이터베이스 라우터에 문제가 있습니다. '레거시'앱을 제외한 모든 앱은 '기본'데이터베이스 (예상)로 라우팅되는 반면 모든 앱과 '레거시'앱은 '레거시'데이터베이스로 라우팅되었습니다.

수정하려면 allow_migrate 함수가 필요했습니다.

def allow_migrate(self, db, app_label, model_name=None, **hints): 

    # Legacy app should only be in legacy database 
    # Return true if app is legacy and database is legacy 

    if app_label == 'legacy': 
     return db == 'legacy' 

    # Legacy database should only contain legacy app 
    # Return true if app is not legacy and database not legacy 

    elif app_label != 'legacy': 
     return db != 'legacy' 

    else: 
     return None 
+0

수정 사항을 질문 끝에 포함하지 말고 별도의 답변으로 추가하십시오. 그렇게하면 문제가 해결 되었음이 분명합니다. – Alasdair

+0

@ Alasdair @ Alasdair 나는 문제가 있었고 해결해야 할 필요가있는 이유를 설명하는 대답을 이미 작성하여 수락했습니다. 대답은 간결함과 중복성 감소라는 질문에서 필요한 구성을 나타냅니다. – tricks

+0

죄송합니다. 이미 답변 하셨다는 점을 발견하지 못했습니다. 제 요점은 당신의 섹션 "The fix"가 대답이 아니라 질문에 있다는 것입니다. – Alasdair

답변

0

대답

문제는 데이터베이스 라우터에 있었다 : 여기에 내가 내 만든 방법이다. '레거시'앱을 제외한 모든 앱은 '기본'데이터베이스 (예상)로 라우팅되는 반면 모든 앱과 '레거시'앱은 '레거시'데이터베이스로 라우팅되었습니다.

해결하려면 '기존'응용 프로그램을 제외한 모든 응용 프로그램을 '기존'데이터베이스로 마이그레이션하지 못하게하는 allow_migrate 기능이 필요했습니다. 자세한 내용은 내 질문에 편집을 참조하십시오.