我想更改模型中特定字段的名称:
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 最简单的方法是什么?
您可以使用 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 creates table names 的方式很重要:
Django 自动从模型类的名称和包含它的应用程序中派生数据库表的名称。模型的数据库表名是通过将模型的“应用标签”(您在 manage.py startapp 中使用的名称)与模型的类名连接起来而构建的,它们之间使用下划线。
如果您有一个多词、驼峰式大小写的模型名称,例如 ProjectItem,则表名称将为 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
没有重命名与列关联的 constraints。迁移仍然有效,但您将拥有以旧列名命名的约束。我有一个具有唯一性约束的列,使用此方法将其重命名,测试唯一性约束是否仍然存在并出现错误,但约束本身的名称仍在使用旧的列名。也许明确的 db.delete_unique
和 db.create_unique
可以做到,但我决定采用 sjh 的解决方案。
我不知道 db.rename 列,听起来很方便,但是过去我将新列添加为一个 schemamigration,然后创建了一个 datamigration 以将值移动到新字段中,然后创建第二个 schemamigration 以删除旧列
db.rename_column
不会为您重命名约束,因此您必须手动处理。如果您忘记执行此操作,则迁移将起作用,但您不知道可能存在仍在使用旧列名的约束。我不清楚这个问题是否只是表面上的问题,或者是否在未来的迁移中应该操纵或放弃约束,South 将无法找到它。无论如何,像 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>
只需更改模型并在 1.9 中运行 makemigrations
Django 自动检测到您已删除并创建了一个字段,并询问:
Did you rename model.old to model.new (a IntegerField)? [y/N]
说是,就会创建正确的迁移。魔法。
将南添加到项目设置文件中已安装的应用程序中。注释掉添加/修改的字段/表。 $ manage.py Schemamigration
如果您使用的是 'pycharm',那么您可以使用 'ctrl+shift+r' 代替 'manage.py' ,并使用 'shift ' 作为参数。