所以大约一年前我开始了一个项目,像所有的新开发人员一样,我并没有太关注结构,但是现在我随着Django的深入,我的项目布局主要是我的模型在结构上很糟糕。
我有模型主要持有在一个单一的应用程序,真的这些模型中的大多数应该在自己的个人应用程序,我确实试图解决这个问题,并将它们向南移动,但我发现由于外键等原因,它很棘手,真的很难。
然而,由于Django 1.7和对迁移的内置支持,现在有没有更好的方法来做到这一点?
发布于 2014-09-04 03:13:09
我正在删除旧答案,因为这可能会导致数据丢失。作为ozan mentioned,我们可以在每个应用程序中创建2个迁移。这篇文章下面的评论引用了我以前的答案。
从第一个应用程序中删除模型的第一个迁移。
$ python manage.py makemigrations old_app --empty
编辑迁移文件以包含这些操作。
class Migration(migrations.Migration):
database_operations = [migrations.AlterModelTable('TheModel', 'newapp_themodel')]
state_operations = [migrations.DeleteModel('TheModel')]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=database_operations,
state_operations=state_operations)
]
第二次迁移依赖于第一次迁移,并在第二个应用程序中创建新表。将模型代码移动到第二个应用程序后
$ python manage.py makemigrations new_app
并将迁移文件编辑为类似下面这样的内容。
class Migration(migrations.Migration):
dependencies = [
('old_app', 'above_migration')
]
state_operations = [
migrations.CreateModel(
name='TheModel',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
],
options={
'db_table': 'newapp_themodel',
},
bases=(models.Model,),
)
]
operations = [
migrations.SeparateDatabaseAndState(state_operations=state_operations)
]
发布于 2014-10-21 02:30:12
使用migrations.SeparateDatabaseAndState
可以相当容易地做到这一点。基本上,我们使用一个数据库操作来同时重命名表,同时使用两个状态操作来从一个应用程序的历史记录中删除模型,并在另一个应用程序的历史记录中创建模型。
从旧应用中删除
python manage.py makemigrations old_app --empty
在迁移中:
class Migration(migrations.Migration):
dependencies = []
database_operations = [
migrations.AlterModelTable('TheModel', 'newapp_themodel')
]
state_operations = [
migrations.DeleteModel('TheModel')
]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=database_operations,
state_operations=state_operations)
]
添加到新应用
首先,将模型复制到新应用程序的model.py中,然后:
python manage.py makemigrations new_app
这将生成一个迁移,将一个简单的CreateModel
操作作为唯一的操作。将其包装在SeparateDatabaseAndState
操作中,这样我们就不会尝试重新创建表。还要将之前的迁移作为依赖项包括在内:
class Migration(migrations.Migration):
dependencies = [
('old_app', 'above_migration')
]
state_operations = [
migrations.CreateModel(
name='TheModel',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
],
options={
'db_table': 'newapp_themodel',
},
bases=(models.Model,),
)
]
operations = [
migrations.SeparateDatabaseAndState(state_operations=state_operations)
]
发布于 2017-11-20 21:23:03
抄袭自我在https://stackoverflow.com/a/47392970/8971048的回答
如果您需要移动模型,并且您不再具有应用程序的访问权限(或者您不想要访问权限),您可以创建一个新的操作,并仅当迁移的模型不存在时才考虑创建新的模型。
在本例中,我将'MyModel‘从old_app传递给我的应用程序。
class MigrateOrCreateTable(migrations.CreateModel):
def __init__(self, source_table, dst_table, *args, **kwargs):
super(MigrateOrCreateTable, self).__init__(*args, **kwargs)
self.source_table = source_table
self.dst_table = dst_table
def database_forwards(self, app_label, schema_editor, from_state, to_state):
table_exists = self.source_table in schema_editor.connection.introspection.table_names()
if table_exists:
with schema_editor.connection.cursor() as cursor:
cursor.execute("RENAME TABLE {} TO {};".format(self.source_table, self.dst_table))
else:
return super(MigrateOrCreateTable, self).database_forwards(app_label, schema_editor, from_state, to_state)
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_some_migration'),
]
operations = [
MigrateOrCreateTable(
source_table='old_app_mymodel',
dst_table='myapp_mymodel',
name='MyModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=18))
],
),
]
https://stackoverflow.com/questions/25648393
复制相似问题