添加“通过”表到 django 字段并随 South 迁移?
看起来这应该是“简单”的,或者至少在某个地方有记录,我只是找不到它。
假设我有一个模型:
class A(models.Model):
users = models.ManyToMany('auth.User', blank=True)
现在我想迁移到一个 through
表,以将字段添加到 ManyToMany 关系中...
class AUsers(models.Model):
user = models.ForeignKey('auth.User')
a = models.ForeignKey('A')
new_field = models.BooleanField()
class A(models.Model):
users = models.ManyToMany('auth.User', blank=True, through='AUsers')
然后我这样做:
% ./manage.py schemamigration app --auto
并不完全令人惊讶,它告诉我它将下降通过表自动创建原始表并为 AUsers
创建一个新表。此时最好的做法是什么?有没有一种不错的方法可以迁移到新的 through
表?我是否在 Meta 中使用 db_table
?我是否不立即使用 through=...
...然后执行 schemamigration --auto
,然后执行 datamigration
进行复制当前表(不知何故,不确定......),然后添加 through
关系并让它杀死表?
这里有什么技巧呢?这真的有那么难吗?
Seems like this should be "easy" or at least documented somewhere, I just cant find it.
Lets say I have a model:
class A(models.Model):
users = models.ManyToMany('auth.User', blank=True)
Now I want to migrate to have a through
table to add fields to the ManyToMany relation...
class AUsers(models.Model):
user = models.ForeignKey('auth.User')
a = models.ForeignKey('A')
new_field = models.BooleanField()
class A(models.Model):
users = models.ManyToMany('auth.User', blank=True, through='AUsers')
Then I do:
% ./manage.py schemamigration app --auto
Not totally surprising, it tells me it is going to drop the original auto-created through table and create a new one for AUsers
. What's the best practice at this point? Is there a decent way to migrate to the new through
table? Do I use db_table
in Meta? Do I just not use the through=...
right away... then do a schemamigration --auto
, then a datamigration
to copy the current table (somehow, not sure...) and then add the through
relation and let it kill the table?
What's the trick here? Is this really that hard?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该能够很轻松地做到这一点。
首先,确保您正在创建的手动直通表在数据库中与 Django 最初自动创建的表具有相同的表名。
因此,首先,让我们在更改之前考虑一个手动模型:
它在功能上(几乎)应该与您以前使用的
ManyToManyField
相同。实际上,您可以进行一个空迁移并应用它,然后使用 --auto 进行更改(但不要这样做)。现在,像上面的示例代码中那样添加字段,然后运行
./manage.py schemamigration appname manual_through_table --empty
。这将为您提供一个名为####_manual_through_table.py
的空迁移。在迁移本身中,将有一个
forwards
和backwards
方法。每一个都需要一行:这应该可以满足您的需求。
You should be able to do this pretty easily.
First of all, make sure that the manual through table that you are creating has the same table name in the database as the one Django originally created automatically.
So, first, let's consider a manual through model before your change:
That should be functionally (almost) identical to the
ManyToManyField
you used to have. Actually, you could make an empty migration and apply it, and then use --auto for your changes (but don't).Now, add your field like you did in your sample code above, and then run
./manage.py schemamigration appname manual_through_table --empty
. That will give you an empty migration named####_manual_through_table.py
.In the migration itself, there will be a
forwards
andbackwards
method. Each one needs to be one line each:That should get you what you are after.
如果有人在尝试使用现代迁移框架做同样的事情时遇到这个问题,请执行以下步骤:
migrations 中。 SingleDatabaseAndState
迁移,其中自动生成的步骤位于state_operations
字段中,数据库操作为空。If anyone comes across this question when trying to do the same thing with the moderns migration framework, here are the steps:
migrations. SeparateDatabaseAndState
migration, where the auto-generated steps are in thestate_operations
field and the database operations are empty.正如评论中提到的,第一步可以使用 < code>db.rename_table 如此处所述,通过模型给出:
然后,使用 --auto 创建迁移(这样您将看到数据库表的名称),并将内容替换为:
我刚刚将其应用到我的项目中,没有出现问题。
As mentioned in a comment, the first step may be simplified using
db.rename_table
as described here, which gives this through model:Then, create a migration with --auto (this way you'll have the names of the DB tables visible), and replace the content with:
I just applied it in my project without issues.