3

プロジェクトの設定には次のスキームがあります。

myproject/
   app1/
   app2/
   appN/
   settings/
      __init__.py
      base.py
      devel.py
      production.py

私のローカル環境では、virtualenvwrapper のpostactivateスクリプト内にあります。

myproject_root=/home/rantanplan/Projects/repos/myproject
cd $myproject_root
export DJANGO_SETTINGS_MODULE=myproject.settings.devel

私が行うworkon myprojectと、プロジェクトのルートディレクトリに変更され、必要なアクティブDJANGO_SETTINGS_MODULEが設定されます。

これは django では問題なく、すべてのコマンド ( などpython manage.py syncdb) が機能します。

一方、次のファブリック タスクがあります。

@task
def syncdb():
    local('python manage.py syncdb --noinput')

これは、単純なsettings.pyファイルを持っていたときに正常に機能していましたが、上記のスキームに変更すると、次の例外が発生します。

django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

Fatal error: local() encountered an error (return code 1) while executing 'python manage.py syncdb --noinput'

Aborting.

いくつかの追加メモ:

  • project関数は、すべての django 設定モジュールが "settings" と名付けられていると (内部的に) 誤って想定しているため、ここでは適用できません。
  • 私はsettings_module関数を無駄にしようとしました。os.environ内部的に使用して環境変数を設定しますが、効果はありません。
  • os.environ['DJANGO_SETTINGS_MODULE']タスク定義の直前を印刷すると、「myproject.settings.devel」が正しく印刷されます。

では、私はここで何を間違っていますか? この問題を解決するにはどうすればよいと思いますか?


手間を省くために、次のようにすることでこれを解決できることを知っていると言わなければなりません。

def syncdb():
    with prefix('export DJANGO_SETTINGS_MODULE=myproject.settings.devel'):
        local('python manage.py syncdb --noinput')

しかし、できればの使用は避けたいと思いprefixます。

また、ハイネクサーが示唆するように、私はできることを知っています:

@task
def syncdb():
    local('python manage.py syncdb --settings=myproject.settings.devel --noinput')

localしかし、なぜが を尊重しないのDJANGO_SETTINGS_MODULEか、なぜsettings_module広告どおりに機能しないのかを知りたいと思っています。

4

2 に答える 2

1

さて、私は問題を見つけましたが、どうすればよいかわかりません。

まず第一に、必要な情報をすべて明らかにしていないようです。

私の django プロジェクトの構造は説明したとおりですが、ファブリックの構造はもう少し複雑です。

基本的に、ファブリックのドキュメントのこの部分のいくつかのパターンに従います

完全な構造は次のとおりです。

deployment/
  __init__.py
  fabric/
    __init__.py
    database.py
    repo.py
    services.py
myproject/
  app1/
  app2/
  appN/
manage.py
fabfile.py

内部deployment/fabric/database.pyには、次のコードがありました。

django.settings_module('myproject.settings.devel')

@task
def syncdb():
    local('python manage.py syncdb --noinput')

そして、私の内部fabfile.pyにはすべてのインポートがありました:

from deployment.fabric.database import dropdb, createdb, syncdb, createuser
from deployment.fabric.something import blahblah

何らかの理由で、現在把握できないようですが、fabfile.py の設定内DJANGO_SETTINGS_MODULE(deployment/fabric/database.py 内で発生していた) は保持されません。

os.environ最初は、アクションがモジュール間で持続しないという誤った認識に達しました! しかし、これは真実ではありません.djangoプロジェクトの外部で同様のシナリオをすぐに構築し、誤った前提を無効にしました.

次に、fabric のlocal機能を調べたところ、本質的には のラッパーであることがわかりましたsubprocess.Popen('...', shell=True)。そのため、以前の実験をテストしsubprocess.Popenましたが、モジュール間で環境変数が保持されていました。

それがファブリックの魔法のタスクのインポートに関係しているのか、それとも私が把握していない基本的なものがあるのか​​ はわかりませんが、以下の方法のいずれかで問題が解決します.

1)prefixコンテキスト マネージャーを使用する

def syncdb():
    with prefix('export DJANGO_SETTINGS_MODULE=myproject.settings.devel'):
        local('python manage.py syncdb --noinput')

2)--settingsコマンドに値を追加localします (hynekcer の説明に従って)。

@task
def syncdb():
    local('python manage.py syncdb --settings=myproject.settings.devel --noinput')

3)settings_moduleタスク内に呼び出しを含めます(ただし、その目的は無効になります)。

@task
def syncdb():
    django.settings_module('myproject.settings.devel')
    local('python manage.py syncdb --noinput')
于 2012-11-14T18:50:21.587 に答える
1

オプションでご利用いただけsettingsます。DJANGO_SETTINGS_MODULE 変数よりも優先されます。

@task
def syncdb():
    local('python manage.py syncdb --settings=myproject.settings.devel --noinput')
于 2012-11-14T00:45:28.983 に答える