使用Django South从具体继承过渡到抽象继承
问题内容:
我有一个现有的Django项目,该项目具有几个使用基类的具体继承的模型。经过仔细考虑,并阅读了诸如Jacob Kaplan-
Moss之类的人所说的话,在我看来,使用这种具体的继承是不必要的。我想迁移为使用抽象基类。
使事情变得复杂的是,我的站点处于活动状态,并且用户输入了数据。因此,在整个过渡过程中,我需要保持所有数据不变。
我将举一个具体的例子:
之前:
app1 / models.py:
class Model1(base_app.models.BaseModel):
field1 = models.CharField(max_length=1000)
field2 = models.CharField(max_length=1000)
app2 / models.py:
class Model2(base_app.models.BaseModel):
field1 = models.CharField(max_length=1000)
field2 = models.CharField(max_length=1000)
base_app / models.py:
class BaseModel(models.Model):
user = models.ForeignKey(User)
another_field = models.CharField(max_length=1000)
后:
app1 / models.py:
class Model1(base_app.models.BaseModel):
field1 = models.CharField(max_length=1000)
field2 = models.CharField(max_length=1000)
app2 / models.py:
class Model2(base_app.models.BaseModel):
field1 = models.CharField(max_length=1000)
field2 = models.CharField(max_length=1000)
base_app / models.py:
class BaseModel(models.Model):
user = models.ForeignKey(User)
another_field = models.CharField(max_length=1000)
class Meta:
abstract = True
现在,我的计划是先将添加abstract = True
到BaseModel。然后,对于每个使用的模型,一次使用BaseModel
一个:
- 使用south来迁移数据库并使用–auto标志创建此迁移
- 使用南方数据迁移。例如,我将遍历Model1中的每个对象,以在BaseModel中获取具有相同pk的对象,并将BaseModel对象的每个字段的值复制到Model1对象。
那么首先,这行得通吗?其次,还有更好的方法吗?
更新:
我的最终解决方案在此处详细介绍:
http://www.markliu.me/2011/aug/23/migrating-a-django-postgres-db-from-
concrete-inhe/
问题答案:
-
添加NewBaseModel,我们使用不同的名称,因此它不会与当前的非抽象名称冲突(South实际上会删除BaseModel)。
class NewBaseModel(models.Model): user = models.ForeignKey(User) another_field = models.CharField(max_length=1000) class Meta: abstract = True
-
将Model1和Model2设置为继承自NewBaseModel
-
运行schemamigration –auto,将向Model1和Model2添加2个新字段
- 运行datamigration –empty并从BaseModel中的值填充新字段
- 加载生产数据库并仔细检查所有已正确迁移的内容
- 删除BaseModel并将NewBaseModel重命名为BaseModel
- 运行schemamigration –auto(这 应该 工作;))
- 部署!
注意:迁移以使用模型架构的当前状态时,请使用 orm 变量。