syncdbの実行中に実行されているからコードを保ちます
-
06-09-2019 - |
質問
私は(それはテーブルが作成される前にモデルにアクセスしようとするため)、エラーをスローするようにsyncdbの実行原因を投げるいくつかのコードを持っています。
syncdbの実行で実行されているからコードを維持する方法はありますか?以下のような何かます:
if not syncdb:
run_some_code()
ありがとう:)
を編集:PS - 私は良い考えであることを、DBにアクセスするコードのために... post_init信号を使用して考えた。デル>
詳細情報
ここで要求されるように、いくつかの詳細は、次のとおりです。)
私はこれに実行したカップルの時間は、例えば...私はジャンゴ-のcronにハッキングし、それがために、インストールされているすべてのアプリケーションを検索するので、あなたがジャンゴを読み込むとき(ジョブが存在していないことを確認することが必要と判断されましたジョブと)とにかく負荷にそれらを追加します。
だから私は__init__.py
ファイルの先頭に次のコードを追加します:
import sqlite3
try:
# Delete all the old jobs from the database so they don't interfere with this instance of django
oldJobs = models.Job.objects.all()
for oldJob in oldJobs:
oldJob.delete()
except sqlite3.OperationalError:
# When you do syncdb for the first time, the table isn't
# there yet and throws a nasty error... until now
pass
明白な理由のために、これはがらくたです。それはsqliteのに関連付けられていますし、私はそこにこのコードを配置するには良い場所がある(これは私が問題時に起こっただけでどのようにある)が、それが動作しています。
は、あなたが得るエラーが運用(sqliteの中に)エラーとスタックトレースで見ることができるようにと言い、「見つからないテーブルdjango_cron_job」の線に沿って何か
ソリューション
最後に、目標は、を任意のページがロードされた前に、のいくつかのコードを実行します。
にしました ページは、(明らかに)提供することができます前に、それをインポートする必要があるため、これは、urls.pyファイルでそれを実行することによって達成することができます。
そして、私は神に感謝:) exceptブロック/その醜い試みを削除することができた(とS.ロット)
解決
「編集:?PS - 私は良い考えであることを、DBにアクセスするコードのために... post_init信号を使用して考えた」
決してます。
あなたは、テーブルが作成される前に、モデルへのアクセスのコードをお持ちの場合は、、あなたは大きな、大きな問題を抱えています。おそらく、真剣に間違って何かをやってます。
通常は、約一回syncdbの実行実行します。データベースが作成されます。そして、あなたのWebアプリケーションがデータベースを使用しています。
時には、あなたはデータベースをドロップして再作成、設計変更を行いました。そして、あなたのWebアプリケーションは、長い時間のためにそのデータベースを使用します。
あなたは(一般的に)__init__.py
モジュール内のコードを必要としません。あなたは(ほとんど)__init__.py
モジュールで実際の作業を行い、実行可能コードを持っていることはありません。それは非常に、非常にまれな、とDjangoには不適切です。
__init__.py
をいじっている理由私はよく分からないときジャンゴのCron あなたはurls.py
であなたのスケジュール手配をすることを言います。
編集
レコードをクリアすると、一つのことです。
__init__.py
とDjango-cronののbase.py
をいじり明確にこれを行うには、完全に間違っている方法です。それは複雑だ場合、あなたはそれが間違ってやっている。
それはあなたが何をしようとして伝えることは不可能だが、それは些細なことする必要があります。
あなたのurls.py
はsyncdbの実行後とORM材料のすべてが構成され、正常にバインドされた後に実行することができます。
あなたのurls.py
は、例えば、いくつかの行を削除して、テーブルにいくつかの行を追加することができます。この時点で、すべてのsyncdbの実行の問題が邪魔されます。
なぜあなたはurls.py
であなたのロジックを持っていないのですか?
他のヒント
は、作成している前モデルにアクセスしようとするコードはかなりは、モジュールレベルでのみ存在することができます。それはあなたの例が示すように、モジュールは、インポートされた実行可能コードの実行をする必要があります。あなたが推測してきたように、これは、syncdbの実行では、失敗した理由です。これは、モジュールをインポートしようとするが、モジュールをインポートする行為は、実行するアプリケーションレベルのコードを引き起こします。 「副作用」あなたがするかどうか。
副作用を引き起こすモジュールの輸入を避けたいという願望は、実行可能なPythonスクリプト用if __name__ == '__main__':
規則が一般的になっていることをPythonでとても強いです。ちょうどコードライブラリをロードすると、アプリケーションが実行を開始させた場合、頭痛が続いて起こる: - )
Djangoのアプリケーションの場合、これは頭痛の種以上になりました。モジュールがインポートされるたびに実行されたoldJob.delete()
の影響を考えてみましょう。それはあなたがDjangoの開発サーバで実行したとき、それは一度だけ実行しているように見えるかもしれませんが、本番環境では、それはかなり頻繁に実行されます。 Apacheを使用する場合は、例えば、Apacheは頻繁に要求を処理するために周りに待機している複数の子プロセスを起動します。長時間実行中のサーバが進むにつれて、あなたのDjangoアプリケーションは、多くの場合、予測できない、モジュールがインポートされ、delete()
が複数回呼び出されることを意味し、ハンドラがWebサーバー用にフォークされるたびに、ブートストラップを取得します。信号は、Apacheのプロセスが同様に初期化されるたびに解雇することができように、信号が、残念ながら、助けにはなりません。
これは、ところで、あなたのコードが誤って実行させることができ、単にWebサーバではありません。あなたはepydocのようなツールを使用する場合は、例えば、これらは、APIドキュメントを生成するために、あなたのコードをインポートします。これは、順番に、明らかにちょうどドキュメントパーサーを実行しているの望ましくない副作用である、アプリケーションロジックが実行を開始する原因となります。
このような理由から、このようなクリーンアップコードは、どちらかのベスト定期的に古いジョブを検索し、DBをクリーンアップするcronジョブによって処理されます。このカスタムスクリプトは、(クリーンなテストの実行を保証するために、展開時に例えば、またはあなたのユニットテストsetUp()
機能の一部として)手動で実行することができ、または任意のプロセスによって。どんなにあなたがそれを行う方法、重要な点は、このようなそのコードが常に実行されるべきではありません。の明示的ではなく、の、の暗黙的にソースファイルを開くことの結果として、の
私はそれが役に立てば幸い。私はそれがsyncdbの実行が実行されているかどうかを決定するための方法を提供していません知っているが、あなたは心の中で生産の展開で、あなたのDjangoアプリケーションを設計する場合syncdbの実行の問題が魔法のように消える。