我想更改模型中特定字段的名称:
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进行此操作最简单的方法是什么?
我想更改模型中特定字段的名称:
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进行此操作最简单的方法是什么?
Answers:
您可以使用该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中使用的名称)连接到模型的类名称,并在其之间加下划线,来构造模型的数据库表名称。
在你有一个多措辞,骆驼套管型号名称的情况下,如项目项,表名会app_projectitem
(即下划线不会之间插入project
和item
即使它们是骆驼式大小写)。
这是我的工作:
myapp/models.py
)./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')
x
还是column_x
?
--auto
迁移是一个很好的技巧。它避免了South ORM Freezer出现的问题,如果迁移仅包含forwards
和backwards
方法,但不包含冻结的model
对象,则会出现该问题。
db.rename_column
不会重命名与列关联的约束。迁移仍然可以进行,但是您将拥有以旧列名称命名的约束。我有一列具有唯一性约束的列,使用此方法将其重命名,测试了唯一性约束仍然存在并收到错误,但是约束本身的名称仍使用旧列名。也许是明确的,db.delete_unique
并且db.create_unique
会做到的,但是我决定采用sjh的解决方案。
我不知道db.rename列,听起来很方便,但是在过去,我将新列添加为一个schemamigration,然后创建了一个datamigration将值移到新字段中,然后创建了另一个schemamigration以删除旧列。
db.rename_column
不会为您重命名约束,因此您必须手动处理它。如果您忘记这样做,则迁移将正常进行,除非您不知道,可能仍然存在使用旧列名的约束。对于我来说,目前还不清楚这个问题是仅仅是表面上的问题,还是将来的迁移中应该操纵约束或放开约束的问题,南方将无法找到它。无论如何,在这里像sjh所建议的那样做是安全的方法:您可以让South弄清楚它应该弄清楚什么。
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>
只需更改模型并makemigrations
在1.9中运行
Django自动检测到您已删除并创建了一个字段,并询问:
Did you rename model.old to model.new (a IntegerField)? [y/N]
同意,就可以创建正确的迁移。魔法。