如何将一个Django应用中的模型迁移至另一个新的应用中?

9 浏览
0 Comments

如何将一个Django应用中的模型迁移至另一个新的应用中?

我有一个包含四个模型的Django应用程序。我现在意识到其中一个模型应该放在一个单独的应用程序中。我已经安装了South用于迁移,但我不认为它可以自动处理这个问题。我应该如何将其中一个模型从旧应用程序迁移到一个新应用程序中?

另外,请记住我需要这个过程可以重复执行,这样我可以迁移生产系统等。

0
0 Comments

如果你想将一个Django模型从一个app迁移到另一个app,这个过程非常简单。Django中的模型与app之间的耦合度并不高,因此迁移相对容易。在Django中,数据库表的名称中包含了app的名称,所以如果你想移动你的app,你可以通过SQL的ALTER TABLE语句来重命名数据库表,或者更简单地,在你的模型的Meta类中使用db_table参数来引用旧名称。

如果你的代码中使用了ContentTypes或者通用关系(generic relations),你可能需要重命名指向正在移动的模型的contenttype的app_label,以保留现有的关系。

当然,如果你不需要保留任何数据,最简单的方法就是完全删除数据库表,并再次运行./manage.py syncdb

那么,如何通过south迁移来实现呢?

0
0 Comments

如何使用south进行迁移。

假设我们有两个应用程序:common和specific:

myproject/

|-- common

| |-- migrations

| | |-- 0001_initial.py

| | `-- 0002_create_cat.py

| `-- models.py

`-- specific

|-- migrations

| |-- 0001_initial.py

| `-- 0002_create_dog.py

`-- models.py

现在我们想要将common.models.cat模型移动到specific应用程序(精确地说是specific.models.cat)。

首先在源代码中进行更改,然后运行:

$ python manage.py schemamigration specific create_cat --auto

+ Added model 'specific.cat'

$ python manage.py schemamigration common drop_cat --auto

- Deleted model 'common.cat'

myproject/

|-- common

| |-- migrations

| | |-- 0001_initial.py

| | |-- 0002_create_cat.py

| | `-- 0003_drop_cat.py

| `-- models.py

`-- specific

|-- migrations

| |-- 0001_initial.py

| |-- 0002_create_dog.py

| `-- 0003_create_cat.py

`-- models.py

现在我们需要编辑两个迁移文件:

#0003_create_cat: 替换现有的前向和后向代码

#只使用一句话:

def forwards(self, orm):

db.rename_table('common_cat', 'specific_cat')

if not db.dry_run:

# 为了在迁移后正常工作的权限

orm['contenttypes.contenttype'].objects.filter(

app_label='common',

model='cat',

).update(app_label='specific')

def backwards(self, orm):

db.rename_table('specific_cat', 'common_cat')

if not db.dry_run:

# 为了在迁移后正常工作的权限

orm['contenttypes.contenttype'].objects.filter(

app_label='specific',

model='cat',

).update(app_label='common')

#0003_drop_cat: 替换现有的前向和后向代码; 添加依赖项:

depends_on = (

('specific', '0003_create_cat'),

)

def forwards(self, orm):

pass

def backwards(self, orm):

pass

现在两个应用程序的迁移都知道了变化,生活变得稍微好一点 🙂

建立迁移之间的这种关系是成功的关键。

现在,如果您执行:

python manage.py migrate common

> specific: 0003_create_cat

> common: 0003_drop_cat

将进行两个迁移,而且

python manage.py migrate specific 0002_create_dog

< common: 0003_drop_cat

< specific: 0003_create_cat

会进行迁移。

请注意,升级模式时我使用了common应用程序,而降级时我使用了specific应用程序。这是因为依赖关系的工作方式。

您可能还需要对django_content_type表进行数据迁移。

如果您将模型从内部项目的一个应用程序移动到外部项目中(其他用户将期望有一个初始迁移),您还可以在drop_cat中进行重命名,并在新应用程序中伪造初始迁移。

非常好的指南。我很好奇,0003_create_cat的后向部分中是否也应该有orm['contenttypes.contenttype'].objects.filter行?另外,我想分享一个提示。如果你有索引,它们也需要修改。在我的情况下,它们是唯一的索引,所以我的前向看起来像这样:db.delete_unique('common_cat', ['col1']) db.rename_table('common_cat', 'specific_cat') db.delete_unique('specific_cat', ['col1'])

为了访问orm['contenttypes.contenttype'],您还需要在schemamigration命令中添加--freeze contenttypes选项。

如果您使用自定义AUTH模型来自django 1.5,则需要在settings.py中更改AUTH_USER_MODEL = 'specific.User'

在我的情况下(Django 1.5.7和South 1.0)..我必须输入python manage.py schemamigration specific create_cat --auto --freeze common才能访问来自common应用程序的cat模型。

在django 1.8中不起作用:unknown command schemamigration

自2016年以来,South已经停止更新!

0
0 Comments

如何将模型从一个Django应用程序迁移到新的应用程序?

有时,涉及外键的情况更加复杂,需要稍微不同的处理方式。

假设我们有两个应用程序common和specific,其中common应用程序中有Cat和Toy两个模型,Toy模型包含一个外键belongs_to指向Cat模型。

现在我们希望将Cat模型从common应用程序迁移到specific应用程序中。

解决方法如下:

首先,在common应用程序的models.py文件中,引入specific应用程序的Cat模型,并删除原先common应用程序中的Cat模型的定义。

然后,在specific应用程序的models.py文件中,定义Cat模型。

接下来,运行以下命令生成迁移文件:

./manage.py schemamigration common --auto

./manage.py schemamigration specific --auto

这样会生成两个迁移文件,一个是common应用程序的迁移文件,一个是specific应用程序的迁移文件。

在common应用程序的迁移文件中,我们需要删除common应用程序中的Cat表,并修改common应用程序中Toy模型的belongs_to外键,将其指向specific应用程序中的Cat模型。

在specific应用程序的迁移文件中,我们需要创建specific应用程序中的Cat表。

此外,为了确保迁移的顺序,我们需要添加一个依赖关系,告诉Django在应用迁移时应该先执行哪个迁移文件。

具体操作如下:

在common应用程序的迁移文件中,添加depends_on属性,并指定依赖的迁移文件。

在specific应用程序的迁移文件中,添加depends_on属性,并指定依赖的迁移文件。

depends_on属性可以确保在向前迁移时,先执行指定的依赖迁移文件,而在向后迁移时,执行的顺序与指定的依赖迁移文件相反。

最后,我们可以运行迁移命令进行数据库迁移。

希望这篇文章对大家有所帮助!

0