使用Django South从具体继承转向抽象继承 [英] Using Django South to move from concrete inheritance to abstract inheritance

查看:111
本文介绍了使用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.mode ls.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)
pre>

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 的每个模型,一次一个:




  • 使用迁移数据库并使用--auto标志创建此迁移

  • 使用南方数据迁移。例如,我将循环遍历Model1中的每个对象,以获取具有相同pk的BaseModel中的对象,并将BaseModel对象的每个字段的值复制到Model1对象。



首先,这个工作吗?第二,有没有更好的方法呢?



更新:



我的最终解决方案在此详细描述:



http://www.markliu.me/2011/aug/23/migrating-a-django-postgres-db-from-concrete-inhe /

解决方案


  1. 添加NewBaseModel,我们使用不同的名称,与当前非抽象的冲突(南方实际上将删除BaseModel)否则

     类NewBaseModel(models.Model): 
    user = models.ForeignKey(User)
    another_field = models.CharField(max_length = 1000)

    class Meta:
    abstract = True


  2. 将Model1和Model2设置为继承自NewBaseModel


  3. 运行模式迁移--auto,将添加2个新字段到Model1和Model2

  4. 运行d atamigration - 空,并从BaseModel中的值填充新字段

  5. 加载生产数据库并仔细检查正确迁移的所有内容

  6. 删除BaseModel并将NewBaseModel重命名为BaseModel

  7. 运行schemamigration --auto(这个应该 work;))

  8. 部署!

注意:迁移时使用 orm 变量来使用模型模式的当前状态。


I have an existing Django project that has several models using concrete inheritance of a base class. After closer consideration, and after reading about what people like Jacob Kaplan-Moss have to say about it, using this concrete inheritance is unnecessary in my case. I would like to migrate to using an abstract base class instead.

The thing that makes this complicated is that my site is live and I have user entered data. Thus, I'll need to keep all my data intact throughout this transition.

I'll give an example to be more concrete:

Before:

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)

After:

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

Right now, my plan is to first add the abstract = True to the BaseModel. Then,for each model that uses BaseModel, one at a time:

  • Use south to migrate the database and create this migration using the --auto flag
  • Use a south data migration. For instance, I would loop through each object in Model1 to fetch the object in BaseModel that has the same pk and copy the values for each field of the BaseModel object to the Model1 object.

So first, will this work? And second, is there a better way to do this?

Update:

My final solution is described in detail here:

http://www.markliu.me/2011/aug/23/migrating-a-django-postgres-db-from-concrete-inhe/

解决方案

  1. Add NewBaseModel, we use different name so it doesn't conflict with current non-abstract one (South would actually delete BaseModel otherwise).

    class NewBaseModel(models.Model):
        user = models.ForeignKey(User)
        another_field = models.CharField(max_length=1000)
    
        class Meta:
            abstract = True
    

  2. Set Model1 and Model2 to inherit from NewBaseModel

  3. Run schemamigration --auto, 2 new fields will be added to Model1 and Model2
  4. Run datamigration --empty and fill new fields from values in BaseModel
  5. Load production db and double check everything migrated correctly
  6. Remove BaseModel and rename NewBaseModel to BaseModel
  7. Run schemamigration --auto (this should work ;) )
  8. Deploy!

NOTE: Use orm variable when migrating to use current state of your model schema.

这篇关于使用Django South从具体继承转向抽象继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆