SchemaEditor¶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()¶渡されたSQL文を実行し、パラメータが指定されている場合はそれも適用します。これは、ユーザーが望む場合にSQLを .sql ファイルにキャプチャできるように、通常のデータベースカーソルの周りに設定されたラッパーです。
create_model()¶提供されたモデルのために、データベースに新しいテーブルを作成し、必要に応じてユニーク制約やインデックスも作成します。
delete_model()¶モデルのテーブルをデータベースから削除し、それに紐づくユニーク制約やインデックスも一緒に削除します。
add_index()¶model のテーブルに index を追加します。
remove_index()¶model のテーブルから index を削除します。
rename_index()¶model のテーブルの old_index を new_index に名前を変更します。
add_constraint()¶model のテーブルに constraint を追加します。
remove_constraint()¶model のテーブルから constraint を削除します。
alter_unique_together()¶モデルの unique_together 値を変更します。これにより、新しい値に一致するまで、モデルのテーブルからユニーク制約が追加または削除されます。
alter_index_together()¶モデルの index_together の値を変更します。これにより、インデックスがモデルのテーブルに追加または削除され、新しい値に一致するようになります。
alter_db_table()¶モデルのテーブル名を old_db_table から new_db_table に変更します。
alter_db_table_comment()¶model のテーブルコメントを new_db_table_comment に変更します。
alter_db_tablespace()¶モデルのテーブルをあるテーブル空間から別のテーブル空間に移動します。
add_field()¶モデルのテーブルにフィールドを表すための列(時には複数)を追加します。フィールドに db_index=True や unique=True が設定されている場合、インデックスやユニーク制約も追加されます。
フィールドが through の値なしで ManyToManyField の場合、カラムを作成する代わりに、リレーションシップを表すためのテーブルを作成します。through が提供されている場合、それは何も操作しません。
フィールドが ForeignKey である場合、これによって外部キー制約もカラムに追加されます。
remove_field()¶フィールドによって追加された、モデルのテーブルからそのフィールドを表す列、および、そのフィールドに関連するユニーク制約、外部キー制約、インデックスを削除します。
フィールドが through の値なしで ManyToManyField の場合、リレーションシップを追跡するために作成されたテーブルを削除します。 through が提供されている場合は何も操作しません。
alter_field()¶この変換により、モデル上のフィールドが古いフィールドから新しいフィールドへと変更されます。これには、カラムの名前の変更 (db_column 属性)、フィールドのタイプの変更 (フィールドクラスが変更された場合)、フィールドの NULL ステータスの変更、フィールド専用のユニーク制約やインデックスの追加または削除、プライマリキーの変更、そして ForeignKey 制約の宛先の変更が含まれます。
これが実行できない最も一般的な変換は、ManyToManyField を通常のフィールドに変換すること、またはその逆です。Django はデータを失うことなくこれを行うことができないため、実行を拒否します。代わりに、remove_field() と add_field() は別々に呼び出されるべきです。
データベースが supports_combined_alters を持っている場合、Django はこれらの操作をできるだけ一つのデータベースコールで実行しようとします。そうでなければ、変更が必要な場合にはそれぞれの変更に対して個別の ALTER 文を発行しますが、変更が必要ない場合には ALTER を発行しません。
特に言及されない限り、すべての属性は読み取り専用です。
connection¶データベースへの connection オブジェクト。connection の便利な属性に、現在アクセスしているデータベースの名前を特定するのに使える alias があります。
特に、この属性は、複数のデータベースに対するマイグレーション を行っているときに役に立ちます。
4月 02, 2025