1

syncdb がエラーをスローするコードがいくつかあります (テーブルが作成される前にモデルにアクセスしようとするため)。

コードが syncdb で実行されないようにする方法はありますか? 何かのようなもの:

if not syncdb:
    run_some_code()

ありがとう :)

edit : PS - データベースにアクセスするコードに post_init シグナルを使用することを考えましたが、それは良い考えですか?

より詳しい情報

リクエストに応じて、ここにいくつかの詳細情報があります:)

たとえば、これに数回遭遇しました...私はdjango-cronをハッキングしていて、djangoをロードするときに既存のジョブがないことを確認する必要があると判断しました(インストールされているすべてのアプリでジョブを検索し、追加するため)とにかくロード中です)。

そこで、__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に関連付けられており、このコードを配置するためのより良い場所があります(これは私が問題に遭遇した方法です)が、機能します。

ご覧のとおり、表示されるエラーは Operational Error (in sqlite) であり、スタック トレースは「table django_cron_job not found」の行に沿って何かを示しています。

解決

最終的な目標は、ページが読み込まれる前にコードを実行することでした。

これは、urls.py ファイルで実行することで実現できます。これは、ページを提供する前にインポートする必要があるためです (明らかに)。

そして、私はその醜いtry/exceptブロックを削除することができました:)神に感謝します(そしてS. Lott)

4

2 に答える 2

4

「編集: PS - データベースにアクセスするコードに post_init シグナルを使用することを考えましたが、それは良い考えですか?」

一度もない。

テーブルが作成される前にモデルにアクセスするコードがある場合、非常に大きな問題が発生します。あなたはおそらく何か深刻な問題を抱えています。

通常、syncdb は約 1 回実行します。データベースが作成されます。また、Web アプリケーションはデータベースを使用します。

場合によっては、設計を変更し、データベースを削除して再作成することがあります。そして、Web アプリケーションはそのデータベースを長時間使用します。

__init__.py(通常)モジュール内のコードは必要ありません。__init__.pyモジュール内で実際に機能する実行可能コードを (ほとんど) 持つべきではありません。これは非常にまれであり、Django には不適切です。

Django Cronが でスケジュールの調整を行うと言った__init__.pyときに、なぜあなたが混乱しているのかわかりません。urls.py


編集

記録をクリアすることは一つのことです。

__init__.pyDjango-cron をいじるのはbase.py、これを行うには明らかに完全に間違った方法です。そんなに複雑なら、やり方が間違っています。

何をしようとしているのかはわかりませんが、些細なことである必要があります。

syncdburls.pyの後、すべての ORM マテリアルが構成され、正しくバインドされた後にのみ実行できます。

たとえば、いくつurls.pyかの行を削除してから、テーブルにいくつかの行を追加できます。この時点で、syncdb の問題はすべて解消されています。

ロジックを に入れてみませんurls.pyか?

于 2009-06-02T01:40:02.393 に答える
2

モデルが作成される前にモデルにアクセスしようとするコードは、ほとんどの場合、モジュール レベルでしか存在できません。あなたの例が示すように、モジュールがインポートされたときに実行可能なコードである必要があります。ご想像のとおり、これが syncdb による失敗の理由です。モジュールをインポートしようとしますが、モジュールをインポートすると、アプリケーション レベルのコードが実行されます。できれば「副作用」。

Python では、副作用の原因となるモジュールのインポートを回避したいという要望が非常に強いif __name__ == '__main__':ため、実行可能な Python スクリプトの規則が一般的になっています。コード ライブラリをロードするだけでアプリケーションの実行が開始されると、頭痛の種になります :-)

Django アプリの場合、これは頭の痛い問題ではありません。oldJob.delete()モジュールがインポートされるたびに実行した場合の影響を考慮してください。Django 開発サーバーで実行すると 1 回だけ実行されるように見えるかもしれませんが、実稼働環境ではかなり頻繁に実行されます。たとえば、Apache を使用している場合、Apache はリクエストの処理を待機している複数の子プロセスを頻繁に起動します。長期実行サーバーが進行するにつれて、Web サーバーのハンドラーが fork されるたびに Django アプリがブートストラップされます。つまり、モジュールがインポートされ、delete()予期せずに何度も呼び出されます。残念ながら、Apache プロセスが初期化されるたびにシグナルが起動される可能性があるため、シグナルは役に立ちません。

ところで、コードが不注意に実行される可能性があるのは単なる Web サーバーではありません。たとえば、epydoc などのツールを使用すると、コードがインポートされて API ドキュメントが生成されます。これにより、アプリケーション ロジックの実行が開始されます。これは、ドキュメント パーサーを実行するだけでは明らかに望ましくない副作用です。

このため、このようなクリーンアップ コードは、古いジョブを定期的に検索して DB をクリーンアップする cron ジョブで処理するのが最適です。setUp()このカスタム スクリプトは、手動で、または任意のプロセスで実行することもできます (たとえば、展開中、またはクリーンなテスト実行を保証するための単体テスト機能の一部として)。どのように行うにせよ、重要な点は、このようなコードは、ソース ファイルを開いた結果として暗黙的に実行されるのではなく、常に明示的に実行される必要があるということです。

それが役立つことを願っています。syncdb が実行されているかどうかを判断する方法が提供されないことはわかっていますが、本番環境へのデプロイを念頭に置いて Django アプリを設計すると、syncdb の問題は魔法のように消えます。

于 2009-06-02T01:21:25.957 に答える