South でテーブル名を変更したい
class Hoge(models.Model): text = models.TextField()
hogeアプリケーションにこんなモデルを作るとデータベースのテーブル名はhoge_hogeになります。
Djangoの外に出ないならこのままでも良いんですけど、データベースを直接見たりSQLを書くにはちょっと格好悪いですよね><
そんな時は
class hoge(models.Model): text = models.TextField() class Meta: db_table = 'hoge'
こんな風にdb_tableを指定してあげると、hogeというテーブルになります。
ただし、Southを使っているとこういう変更もmigrationファイルを作る必要があります。
datamigrationを利用して
class Migration(SchemaMigration): def forwards(self, orm): db.rename_table('hoge_hoge', 'hoge') # backwards以下省略
rename_tableを実行するmigrationファイルを作るとテーブル名が変更出来ます。
簡単ですね!
落とし穴あるよー
名前を変えたテーブルが他のテーブルと関連していない場合はこれで大丈夫ですが、関連しているテーブルがあると問題が起こる場合があります。
例えば、hugaアプリケーションにこんなモデルがあるとします。
class Huga(models.Model): hoge = models.ForeignKey(Hoge)
そして、settingsのINSTALLED_APPSが
INSTALLED_APPS = ( 'south', 'hoge', 'huga' )
こんな風になってるとエラーが発生する場合があります。
migrationをする時はINSTALLED_APPSの上から順に、そのアプリにある全てのmigrationが実行されるので
1. hogeアプリ:hoge_hoge の create
2. hogeアプリ:hoge_hoge から hoge への rename
3. hugaアプリ:hoge_hoge への ForeignKey を持つ huga の create
となって、hugaにアクセスすると、hoge_hogeなんてテーブルないよ!とエラーが発生するのです。
当たり前な解決策
INSTALLED_APPSの順番をhugaを上にするだけで、この問題は解決します。
migrationの実行順が
1. hugaアプリ:hoge_hoge への ForeignKey を持つ huga の create
2. hogeアプリ:hoge_hoge の create
3. hogeアプリ:hoge_hoge から hoge への rename
となって、hoge_hoge から hoge への rename で、huga の ForeignKey も hoge にちゃんと変更されます。
普通に書いてるとForeignKeyを張られる方を上に書きがちなのですが、普段からForeignKeyを張る方を上に書くようにしてるとこーゆー無駄なのに引っかからずに良いのではないでしょうか。