2011-07-05 6 views
25

나는 django를 평가 해 왔으며 다음과 같은 것이 가능한지 궁금해했습니다. 나는 이미 정규 다중 데이터베이스 문서를 보았으므로이 유스 케이스는 내가 말할 수있는만큼 언급되지 않았기 때문에 저를 지적하지 마십시오. 내가 틀렸다면 다시 받아들이십시오 :)Django 다중 및 동적 데이터베이스

대부분의 내 응용 프로그램 모델이있는 하나의 기본 데이터베이스를 원하지만 응용 프로그램 중 하나는 데이터베이스를 동적으로 생성해야하며 고객 별 데이터베이스가 필요합니다.

데이터베이스 경로 (sqlite를 사용할 계획 임)는 기본 데이터베이스에 저장되므로 커서를 변경해야하지만 모델은 동일하게 유지됩니다.

이 방법에 대한 의견을 보내 주시면 감사하겠습니다.

+0

왜 여러 데이터베이스를 사용해야합니까? 각 고객에 대한 정보를 보유하도록 앱 모델 스키마를 조정할 수없는 이유가 있습니까? 각 고객에 대해 여러 개의 데이터베이스가있는 것은 매우 불규칙합니다. –

+0

현재 적절한 아키텍처를 결정하려고합니다. 여러 데이터베이스를 사용하지 않아도되지만 휴대용, 온라인 및 오프라인으로 서비스를 제공하는 옵션 중 하나입니다. 그리고이 목적으로 가능한지, 개념적으로는 상당히 간단하다는 것을 알고 싶습니다. 그러나 실제로 이것을 일반적인 프레임 워크에서 지원하는 것은 까다로울 수 있으므로 누군가 전에 이런 식으로 작업을했는지 알았을 것입니다. – nickjb

+1

가능한 [Django : 동적 데이터베이스 파일] (http://stackoverflow.com/questions/14254315/django-dynamic-database-file) (참고 : 링크 된 질문은 적절한 솔루션을 제공하는 것으로 보이며 – mgibsonbr

답변

24

"You should not edit settings at runtime"으로 열립니다.

그런데 나는 각 사용자마다 고유 한 데이터베이스를 만들고자 할 때와 똑같은 문제가 있다고 말합니다. 이 작업을 수행하는 이유는 사용자가 내 서버에 저장되지 않은 데이터베이스에 저장/액세스 할 수있는 기능을 제공하기 때문에 여러 데이터베이스가 필요하며 각 사용자마다 하나씩 필요합니다.

이 답변은 원하는 목표를 달성하는 데 권장되는 방법이 아닙니다. 나는 장고 전문가에게이 문제에 최선의 방법으로 접근하는 것을 듣고 싶다. 그러나 이것은 제가 사용 해본 솔루션이며 지금까지 잘 작동했습니다. 그러나 sqlite를 사용하고 있지만 데이터베이스 중 하나에 대해 쉽게 수정할 수 있습니다. 서버가 재시작 될 때 (런타임에) 다시로드에 대해 이러한 설정을 저장하는 파일을 만듭니다

    1. (실행시) 설정으로 새 데이터베이스를 추가
    2. :

      요약

      ,이 과정이다

    3. 실행 (서버가 재시작 될 때마다)에 저장된 설정 파일을로드하는 스크립트 이제

    , 어떻게 이것을 달성하기 위해 :

    1) 처음에는 새 사용자를 만들 때 설정에서 새 데이터베이스를 만듭니다. 이 코드는 새로운 사용자가 만들어지는 내 관점에서 살아납니다.

    from YOUR_PROJECT_NAME import settings 
    database_id = user.username #just something unique 
    newDatabase = {} 
    newDatabase["id"] = database_id 
    newDatabase['ENGINE'] = 'django.db.backends.sqlite3' 
    newDatabase['NAME'] = '/path/to/db_%s.sql' % database_id 
    newDatabase['USER'] = '' 
    newDatabase['PASSWORD'] = '' 
    newDatabase['HOST'] = '' 
    newDatabase['PORT'] = '' 
    settings.DATABASES[database_id] = newDatabase 
    save_db_settings_to_file(newDatabase) #this is for step 2) 
    

    이 스크립트는 '런타임시 데이터베이스 설정을 django 프로젝트 설정으로로드합니다. 그러나 서버가 다시 시작되면이 데이터베이스는 더 이상 설정되지 않습니다.

    2) 서버를 다시 시작할 때마다 자동으로 이러한 설정을 다시로드하기 위해 서버를 시작할 때마다로드 될 각 데이터베이스에 대한 파일을 만듭니다. 이 파일을 생성하는 기능 save_db_settings_to_file에 의해 수행됩니다

    def save_db_settings_to_file(db_settings): 
        path_to_store_settings = "/path/to/your/project/YOUR_PROJECT_NAME/database_settings/" 
        newDbString = """ 
    DATABASES['%(id)s'] = { 
        'ENGINE': '%(ENGINE)s', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 
        'NAME': '%(NAME)s',      # Or path to database file if using sqlite3. 
        'USER': '',      # Not used with sqlite3. 
        'PASSWORD': '',     # Not used with sqlite3. 
        'HOST': '',      # Set to empty string for localhost. Not used with sqlite3. 
        'PORT': '',      # Set to empty string for default. Not used with sqlite3. 
    } 
        """ % db_settings 
        file_to_store_settings = os.path.join(path_to_store_settings, db_settings['id'] + ".py") 
        write_file(file_to_store_settings, newDbString) #psuedocode for compactness 
    

    3) 실제로 서버가 시작될 때, 내가 설정 폴더에 각 파일을로드 /path/to/your/project/YOUR_PROJECT_NAME/settings.py의 맨 아래에 한 줄을 추가 설정을로드하려면 데이터베이스 세부 정보를 설정에로드하는 효과가 있습니다.

    from settings import DATABASES 
    import os 
    
    path_to_store_settings = "/path/to/your/project/YOUR_PROJECT_NAME/database_settings/" 
    for fname in os.listdir(path_to_settings): 
        full_path = os.path.join(path_to_settings, fname) 
        f = open(full_path) 
        content = f.read() 
        f.close() 
        exec(content) #you'd better be sure that the file doesn't contain anything malicious 
    

    참고 가져 오기 문 대신 settings.py의 하단에 직접 코드를 넣을 수 있습니다 :

    import settings_manager 
    

    그런 import settings_manager는 다음 코드가 포함 /path/to/your/project/YOUR_PROJECT_NAME/settings_manager.py에서 파일을로드 , import 문을 사용하면 추상화 수준의 settings.py가 일관되게 유지됩니다.

    이것은 설정에서 데이터베이스를 제거하기 만하면 설정 파일을 삭제하고 서버가 다시 시작될 때 설정에 세부 정보를로드하지 않기 때문에 각 데이터베이스 설정을로드하는 편리한 방법입니다 , 데이터베이스에 액세스 할 수 없습니다.

    내가 말했듯이,이 작품과 나는 지금까지 그것을 사용하여 성공했지만 이것이 이상적인 솔루션이 아닙니다. 누군가가 더 나은 해결책을 게시 할 수 있다면 정말 감사 할 것입니다. 나쁜 그것에 대해 무엇

    는 :

    • 이 명시 적으로 런타임에 설정을 수정하지 장고 팀의 조언을 무시한다. 나는이 충고가 주어지는 이유를 모른다.
    • exec 문을 사용하여 설정에 데이터를로드합니다. 이것은 괜찮을 것입니다.하지만 파일 중 하나에서 손상되거나 악성 코드가 발생하면 슬픈 팬더가됩니다.

    아직 auth 및 sessions 데이터에 대한 기본 데이터베이스를 사용하지만 내 앱의 모든 데이터는 사용자 별 데이터베이스에 저장된다는 점에 유의하십시오.

  • +0

    데이터베이스를 사용하여 (파일을 통해) 방법을 구현했지만 데이터베이스 자체를이 파일의 저장소로 사용했지만 다른 솔루션을 제공했습니다. . settings.py의 마지막 줄은 데이터베이스 정의가 들어있는 모든 모델을로드하고 django의 DATABASE 설정에 추가합니다. –

    +2

    기본 데이터베이스 (사용자를 관리하는 데이터베이스)에 db 연결을 쓰면 텍스트 파일보다 더 우아하게 만들 수 있습니다. – JulienD

    7

    @ thedawnrider의 답변을 보완하기 위해 경우에 따라 settings.DATABASES 편집이 충분하지 않을 수 있습니다. django.db.connections.databases은 캐시와 래퍼로 사용되며 settings.DATABASES을 중심으로 수정하는 것이 더 신뢰할 수 있습니다.

    from django.db import connections 
    database_id = user.username #just something unique 
    newDatabase = {} 
    newDatabase["id"] = database_id 
    newDatabase['ENGINE'] = 'django.db.backends.sqlite3' 
    newDatabase['NAME'] = '/path/to/db_%s.sql' % database_id 
    newDatabase['USER'] = '' 
    newDatabase['PASSWORD'] = '' 
    newDatabase['HOST'] = '' 
    newDatabase['PORT'] = '' 
    connections.databases[database_id] = newDatabase