[解決済み] モデルとリレーションシップフィールドの名前を変更するためのDjangoマイグレーション戦略
質問
既存の Django プロジェクトで、いくつかのモデルの名前を変更しようと思っています。そのモデルには、名前を変更したいモデルと外部キー関係を持つ他のモデルが多数存在します。この場合、複数のマイグレーションが必要であることは間違いないのですが、正確な手順がわかりません。
という Django アプリの中で、次のようなモデルから始めるとします。
myapp
:
class Foo(models.Model):
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)
class AnotherModel(models.Model):
foo = models.ForeignKey(Foo)
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
foo = models.ForeignKey(Foo)
is_ridonkulous = models.BooleanField()
の名前を変更したい。
Foo
というのも、この名前はあまり意味がなく、コードの混乱を引き起こしているからです。
Bar
の方がより明確な名前になります。
Djangoの開発ドキュメントを読んだ限りでは、以下のような移行戦略を想定しています。
ステップ1
修正
models.py
:
class Bar(models.Model): # <-- changed model name
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)
class AnotherModel(models.Model):
foo = models.ForeignKey(Bar) # <-- changed relation, but not field name
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
foo = models.ForeignKey(Bar) # <-- changed relation, but not field name
is_ridonkulous = models.BooleanField()
注意
AnotherModel
のフィールド名は
foo
は変更されませんが、リレーションが更新されて
Bar
というモデルを作成しました。私の推論は、一度に多くを変更すべきではなく、もしこのフィールド名を
bar
そのカラムのデータを失う危険性があるのです。
ステップ2
空のマイグレーションを作成します。
python manage.py makemigrations --empty myapp
ステップ3
を編集します。
Migration
クラスを追加し、ステップ 2 で作成したマイグレーションファイルの
RenameModel
演算を演算リストに追加します。
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RenameModel('Foo', 'Bar')
]
ステップ4
マイグレーションを適用します。
python manage.py migrate
ステップ5
の関連フィールド名を編集します。
models.py
:
class Bar(models.Model):
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)
class AnotherModel(models.Model):
bar = models.ForeignKey(Bar) # <-- changed field name
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
bar = models.ForeignKey(Bar) # <-- changed field name
is_ridonkulous = models.BooleanField()
ステップ6
別の空のマイグレーションを作成します。
python manage.py makemigrations --empty myapp
ステップ7
を編集します。
Migration
クラスを追加し、ステップ 6 で作成したマイグレーションファイルの
RenameField
の操作に関連するフィールド名を操作リストに追加します。
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_rename_fields'), # <-- is this okay?
]
operations = [
migrations.RenameField('AnotherModel', 'foo', 'bar'),
migrations.RenameField('YetAnotherModel', 'foo', 'bar')
]
ステップ8
2回目のマイグレーションを適用します。
python manage.py migrate
新しい変数名を反映させるために残りのコード(ビュー、フォームなど)を更新することは別として、新しいマイグレーション機能は基本的にこのように動作するのでしょうか?
また、手順が多いように思います。何らかの方法で移行作業を凝縮できないでしょうか?
ありがとうございます。
解決方法は?
で、やってみると、どうやらStep3~7を凝縮することができるようです。
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RenameModel('Foo', 'Bar'),
migrations.RenameField('AnotherModel', 'foo', 'bar'),
migrations.RenameField('YetAnotherModel', 'foo', 'bar')
]
admin.pyや古いマイグレーションファイル(!)など、インポートされている名前を更新しないと、エラーが発生する可能性があります。
更新
: として
シーザロ
が言及しているように、新しいバージョンの Django は通常、モデルがリネームされたかどうかを検出し、尋ねることができます。そこで
manage.py makemigrations
をまず確認し、その後マイグレーションファイルを確認してください。
関連
-
ピロウズ画像色処理の具体的な活用方法
-
Python Decorator 練習問題
-
Python Pillow Image.save jpg画像圧縮問題
-
FacebookオープンソースワンストップサービスpythonのタイミングツールKats詳細
-
[解決済み】RuntimeWarning: invalid value encountered in double_scalars で numpy の除算ができない。
-
[解決済み】RuntimeWarning: 割り算で無効な値が発生しました。
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み】NameError: 名前 'self' が定義されていません。
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み】Djangoでnull=Trueとblank=Trueの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
PythonによるLeNetネットワークモデルの学習と予測
-
PicgoのイメージベッドツールをPythonで実装する
-
Pythonショートビデオクローラーチュートリアル
-
[解決済み] データ型が理解できない
-
[解決済み】socket.error: [Errno 48] アドレスはすでに使用中です。
-
[解決済み】SyntaxError: デフォルト以外の引数がデフォルトの引数に続く
-
[解決済み] TypeError: 'DataFrame' オブジェクトは呼び出し可能ではない
-
[解決済み】ValueError: pickleプロトコルがサポートされていません。3、python2 pickleはpython3 pickleでダンプしたファイルを読み込むことができない?
-
[解決済み] 2つのDjangoアプリ間でモデルを移動させる方法 (Django 1.7)
-
[解決済み] Django/South を使ってモデルの名前を変更する最も簡単な方法とは?