web-dev-qa-db-ja.com

Django-Southを使用してモデルフィールドの名前を変更するには?

モデル内の特定のフィールドの名前を変更したい:

class Foo(models.Model):
    name = models.CharField()
    rel  = models.ForeignKey(Bar)

変更する必要があります:

class Foo(models.Model):
    full_name     = models.CharField()
    odd_relation  = models.ForeignKey(Bar)

Southを使用してこれを行う最も簡単な方法は何ですか?

208
Jonathan

db.rename_column 関数を使用できます。

class Migration:

    def forwards(self, orm):
        # Rename 'name' field to 'full_name'
        db.rename_column('app_foo', 'name', 'full_name')




    def backwards(self, orm):
        # Rename 'full_name' field to 'name'
        db.rename_column('app_foo', 'full_name', 'name')

db.rename_columnの最初の引数はテーブル名であるため、 Djangoがテーブル名を作成する :を覚えておくことが重要です。

Djangoは、モデルクラスとそれを含むアプリの名前からデータベーステーブルの名前を自動的に導き出します。モデルのデータベーステーブル名は、モデルの「アプリラベル」(manage.py startappで使用した名前)をモデルのクラス名にアンダースコアを付けて結合することで構築されます。

ProjectItemなど、複数の単語からなるキャメルケースのモデル名がある場合、テーブル名はapp_projectitemになります(つまり、projectitemの間にアンダースコアは挿入されません-ケース)。

229
googletorp

ここに私がやることがあります:

  1. モデルの列名を変更します(この例ではmyapp/models.pyになります)
  2. ./manage.py schemamigration myapp renaming_column_x --autoを実行します

renaming_column_xには任意の名前を指定できます。これは、移行ファイルにわかりやすい名前を付ける方法にすぎません。

これにより、古い列を削除して新しい列を追加するmyapp/migrations/000x_renaming_column_x.pyというファイルが生成されます。

このファイルのコードを変更して、移行動作を単純な名前変更に変更します。

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Renaming column 'mymodel.old_column_name' to 'mymodel.new_column_name'
        db.rename_column(u'myapp_mymodel', 'old_column_name', 'new_column_name')

    def backwards(self, orm):
        # Renaming column 'mymodel.new_column_name' to 'mymodel.old_column_name'
        db.rename_column(u'myapp_mymodel', 'new_column_name', 'old_column_name')
39
donturner

Db.rename列については知りませんでしたが、以前は新しい列を1つのスキーマ移行として追加し、値を新しいフィールドに移動するデータ移行を作成してから、2番目のスキーマ移行で古い列を削除しました

15
sjh

Django 1.7で Migrations が導入されたため、移行を管理するために追加のパッケージをインストールする必要さえありません。

モデルの名前を変更するには、最初に空の移行を作成する必要があります。

$ manage.py makemigrations <app_name> --empty

次に、移行のコードを次のように編集する必要があります。

from Django.db import models, migrations

class Migration(migrations.Migration):

dependencies = [
    ('yourapp', 'XXXX_your_previous_migration'),
]

operations = [
    migrations.RenameField(
        model_name='Foo',
        old_name='name',
        new_name='full_name'
    ),
    migrations.RenameField(
        model_name='Foo',
        old_name='rel',
        new_name='odd_relation'
    ),
]

その後、実行する必要があります:

$ manage.py migrate <app_name>
9

モデルを変更して1.9でmakemigrationsを実行するだけです

Djangoは、ユーザーが1つのフィールドを削除して作成したことを自動的に検出し、次の質問をします。

Did you rename model.old to model.new (a IntegerField)? [y/N]

はいと言うと、適切な移行が作成されます。魔法。

  1. プロジェクト設定ファイルでインストール済みアプリにsouthを追加します。
  2. 追加/変更されたフィールド/テーブルをコメント化します。
  3. $ manage.py Schemamigration <app_name> --initial
  4. $ manage.py migrate <app_name> --Fake
  5. フィールドのコメントを外し、変更したものを書き込みます
  6. $ manage.py Schemamigration --auto
  7. $ manage.py migrate <app_name>

「pycharm」を使用している場合は、「manage.py」の代わりに「ctrl + shift + r」を使用し、パラメーターに「shift」を使用できます。

0
ancho