2011-07-05 34 views
25

私はdjangoを評価しており、次のことが可能かどうか疑問に思っています。私はすでに正規の複数のデータベースのドキュメントを見てきましたので、このユースケースは私が作ることができる限り言及されていないので、私にそれを指摘してはいけません。私が間違っている場合は、私はそれを取り戻す:)Djangoの複数の動的データベース

私のアプリケーションのモデルのほとんどが常駐する1つのメインデータベースが必要ですが、アプリケーションの1つはデータベースを動的に作成する必要があり、これらは顧客固有のデータベースになります。

データベースパス(私はsqliteを使用する予定です)はプライマリデータベースに格納されるため、カーソルを変更する必要がありますが、モデルは同じままです。

私はこれを達成するためのあらゆる考えを歓迎しますか?

+0

なぜ複数のデータベースを使用する必要がありますか?各顧客の情報を保持するためにアプリモデルのスキーマを調整できない理由はありますか?顧客ごとに複数のデータベースを持つことは非常に不規則です。 –

+0

私は現時点で適切なアーキテクチャを決定しようとしています。私は複数のデータベースを使用する必要はありませんが、ポータブル、オンライン、オフラインのサービスを提供するオプションの1つです。そして、この目的のために、私はそれが可能かどうかを知りたいのですが、それは概念的にはかなり簡単ですが、実際には一般的な枠組みでこれをサポートするのは難しいかもしれないので、誰かが前にこのようなことをしていれば、 – nickjb

+1

[Django:dynamic database file](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 
    

    (注)import文の代わりにsettings.pyの下部に直接コードを入れることができます:

    import settings_manager 
    

    その後、import settings_managerは、次のコードが含まれています/path/to/your/project/YOUR_PROJECT_NAME/settings_manager.pyでファイルをロードしますimport文を使用すると、settings.pyの抽象レベルが一貫して保持されます。

    これは、各データベース設定をロードする便利な方法です。設定からデータベースを削除するには、設定ファイルを削除し、次にサーバーを再起動してもその詳細を設定にロードしないためですデータベースにはアクセスできません。

    私が言ったように、これはうまくいきましたが、今までそれを使って成功しましたが、これは理想的な解決策ではありません。私は誰かがより良い解決策を投稿できるかどうか本当に感謝します。

    それについて悪い何ですか:

    • それは明示的に実行時に設定を変更しないDjangoのチームからのアドバイスを挑みます。私はこのアドバイスが与えられた理由を知らない。
    • 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 
    
    関連する問題