は、私は時々、この問題に(他の回答を読んで、おそらくそれは型破りではありません)型破りなアプローチをとっています。私はちょうどそれをいくつかの実験を行ったので、私はジャンゴでそれを試したことはありません。要するに
、私はコードが古いスキーマから生じた例外をキャッチし、適切なスキーマのアップグレードを適用してみましょう。私はこれが受け入れられた答えであるとは期待していません。それは、場合によっては(そして決して論外かもしれない)場合にのみ適切です。しかし、私はそれが醜い鴨の優雅さを持っていると思う。もちろん
、私は任意の時点で生産状態にリセットすることができ、テスト環境を持っています。そのテスト環境を使用して、私はいつものように自分のスキーマを更新し、それに対してコードを書く。
次に、スキーマの変更を元に戻して、新しいコードを再度テストします。結果のエラーを捕捉し、スキーマのアップグレードを実行して、間違ったクエリを再試行します。それは一度だけ働き(生産に入れたときに起こり得るような)を複数回呼ばれていた場合ように、それは「害しない」になるよう
アップグレード機能を記述する必要があります。
実際のPythonコード - 私はコンセプトをテストするために私のsettings.pyの終わりにこれを置くが、あなたはおそらく別のモジュールでそれを維持したいでしょう:
from django.db.models.sql.compiler import SQLCompiler
from MySQLdb import OperationalError
orig_exec = SQLCompiler.execute_sql
def new_exec(self, *args, **kw):
try:
return orig_exec(self, *args, **kw)
except OperationalError, e:
if e[0] != 1054: # unknown column
raise
upgradeSchema(self.connection)
return orig_exec(self, *args, **kw)
SQLCompiler.execute_sql = new_exec
def upgradeSchema(conn):
cursor = conn.cursor()
try:
cursor.execute("alter table users add phone varchar(255)")
except OperationalError, e:
if e[0] != 1060: # duplicate column name
raise
本番環境が起動したら現在までに、この自己アップグレードコードをコードベースから削除することは自由です。しかし、あなたがそうしなくても、コードは重大な不必要な作業をしていません。
私のケースでは例外クラス(私の場合はMySQLdb.OperationalError)と数字(1054「不明な列」/ 1060「重複列」)をデータベースエンジンとスキーマの変更に合わせる必要がありますが、簡単です。
他のいくつかの問題ではなく、問題のスキーマ変更のために実行中のSQLが実際にエラーが発生していることを確認するために追加のチェックを追加したい場合があります。唯一の不利な点は、そのような状況では、例外を発生させる前にアップグレードと悪質なクエリを2回試行するということです。
のpythonについての私の好きなものの一つは、簡単にこのような実行時にシステム・メソッドをオーバーライドする自分の能力です。非常に柔軟性があります。
ほとんどのDjango開発者は私が南を使用していることを知っています。私は自分自身を使用します。あなたはそれが「かなりたくさん見逃す」と思いますか?私は南との不平を抱いていたが、ほとんどの場合、それは機能する。 – super9
アプリケーションのおおよその容量は? – David542