# Django 5.2.8 ドキュメント

# `SchemaEditor`

class BaseDatabaseSchemaEditor

Django のマイグレーションシステムは2つの部分に分かれています。データベースに対してどのような操作を実行するべきかを計算してその結果を保管するロジックの部分　(`django.db.migrations`)と、「モデルを作成する」や「フィールドを削除する」といった操作を SQL に変換する、データベースの抽象レイヤーの部分です。後者の仕事を担当するのが、 `SchemaEditor` です。

Django を使っている普通の開発者が `SchemaEditor` を直接扱うことはほとんどありませんが、自前のマイグレーションシステムを実装したい場合や、より高度なことが必要になった場合には、SQL を書くのではなく、こちらを選びましょう。

Django のデータベースのバックエンドは、それぞれ対応するバージョンの `SchemaEditor` を提供しており、好きなときに `connection.schema_editor()` コンテキストマネージャを使ってアクセスできます。

    with connection.schema_editor() as schema_editor:
        schema_editor.delete_model(MyModel)

これは、トランザクションや遅延SQL (`ForeignKey` 制約の作成など) のようなものを管理することを可能にするため、コンテキストマネージャを通して使用されなければなりません。

すべての可能な操作をメソッドとして公開し、変更を適用したい順序で呼び出すべきです。一部の操作や変更の種類は、すべてのデータベースで可能ではありません。例えば、MyISAM は外部キー制約をサポートしていません。

Django のマイグレーション機能を使うためには、サードパーティ製のデータベースバックエンドを書いたり保守したりする場合、 `SchemaEditor` の実装を提供する必要があります。しかし、データベースが SQL の使用やリレーショナルデザインにおいて比較的標準的である限り、組み込みの Django `SchemaEditor` クラスの一つをサブクラス化して、文法を少し変更するだけで済むはずです。

## メソッド

### `execute()`

BaseDatabaseSchemaEditor.execute(sql, params=())

渡されたSQL文を実行し、パラメータが指定されている場合はそれも適用します。これは、ユーザーが望む場合にSQLを `.sql` ファイルにキャプチャできるように、通常のデータベースカーソルの周りに設定されたラッパーです。

### `create_model()`

BaseDatabaseSchemaEditor.create_model(model)

提供されたモデルのために、データベースに新しいテーブルを作成し、必要に応じてユニーク制約やインデックスも作成します。

### `delete_model()`

BaseDatabaseSchemaEditor.delete_model(model)

モデルのテーブルをデータベースから削除し、それに紐づくユニーク制約やインデックスも一緒に削除します。

### `add_index()`

BaseDatabaseSchemaEditor.add_index(model, index)

`model` のテーブルに `index` を追加します。

### `remove_index()`

BaseDatabaseSchemaEditor.remove_index(model, index)

`model` のテーブルから `index` を削除します。

### `rename_index()`

BaseDatabaseSchemaEditor.rename_index(model, old_index, new_index)

`model` のテーブルの `old_index` を `new_index` に名前を変更します。

### `add_constraint()`

BaseDatabaseSchemaEditor.add_constraint(model, constraint)

`model` のテーブルに `constraint` を追加します。

### `remove_constraint()`

BaseDatabaseSchemaEditor.remove_constraint(model, constraint)

`model` のテーブルから `constraint` を削除します。

### `alter_unique_together()`

BaseDatabaseSchemaEditor.alter_unique_together(model, old_unique_together, new_unique_together)

モデルの `unique_together` 値を変更します。これにより、新しい値に一致するまで、モデルのテーブルからユニーク制約が追加または削除されます。

### `alter_index_together()`

BaseDatabaseSchemaEditor.alter_index_together(model, old_index_together, new_index_together)

モデルの `index_together` の値を変更します。これにより、インデックスがモデルのテーブルに追加または削除され、新しい値に一致するようになります。

### `alter_db_table()`

BaseDatabaseSchemaEditor.alter_db_table(model, old_db_table, new_db_table)

モデルのテーブル名を `old_db_table` から `new_db_table` に変更します。

### `alter_db_table_comment()`

BaseDatabaseSchemaEditor.alter_db_table_comment(model, old_db_table_comment, new_db_table_comment)

`model` のテーブルコメントを `new_db_table_comment` に変更します。

### `alter_db_tablespace()`

BaseDatabaseSchemaEditor.alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)

モデルのテーブルをあるテーブル空間から別のテーブル空間に移動します。

### `add_field()`

BaseDatabaseSchemaEditor.add_field(model, field)

モデルのテーブルにフィールドを表すための列（時には複数）を追加します。フィールドに `db_index=True` や `unique=True` が設定されている場合、インデックスやユニーク制約も追加されます。

フィールドが `through` の値なしで `ManyToManyField` の場合、カラムを作成する代わりに、リレーションシップを表すためのテーブルを作成します。`through` が提供されている場合、それは何も操作しません。

フィールドが `ForeignKey` である場合、これによって外部キー制約もカラムに追加されます。

### `remove_field()`

BaseDatabaseSchemaEditor.remove_field(model, field)

フィールドによって追加された、モデルのテーブルからそのフィールドを表す列、および、そのフィールドに関連するユニーク制約、外部キー制約、インデックスを削除します。

フィールドが `through` の値なしで ManyToManyField の場合、リレーションシップを追跡するために作成されたテーブルを削除します。 `through` が提供されている場合は何も操作しません。

### `alter_field()`

BaseDatabaseSchemaEditor.alter_field(model, old_field, new_field, strict=False)

この変換により、モデル上のフィールドが古いフィールドから新しいフィールドへと変更されます。これには、カラムの名前の変更 (`db_column` 属性)、フィールドのタイプの変更 (フィールドクラスが変更された場合)、フィールドの `NULL` ステータスの変更、フィールド専用のユニーク制約やインデックスの追加または削除、主キーの変更、そして `ForeignKey` 制約の宛先の変更が含まれます。

これが実行できない最も一般的な変換は、`ManyToManyField` を通常のフィールドに変換すること、またはその逆です。Django はデータを失うことなくこれを行うことができないため、実行を拒否します。代わりに、`remove_field()` と `add_field()` は別々に呼び出されるべきです。

データベースが `supports_combined_alters` を持っている場合、Django はこれらの操作をできるだけ一つのデータベースコールで実行しようとします。そうでなければ、変更が必要な場合にはそれぞれの変更に対して個別の ALTER 文を発行しますが、変更が必要ない場合には ALTER を発行しません。

## 属性

特に言及されない限り、すべての属性は読み取り専用です。

### `connection`

SchemaEditor.connection

データベースへの connection オブジェクト。connection の便利な属性に、現在アクセスしているデータベースの名前を特定するのに使える `alias` があります。

特に、この属性は、複数のデータベースに対するマイグレーション を行っているときに役に立ちます。