Django 1.7.4, PostgreSQL: Migrate FK to M2M?

36 views
Skip to first unread message

Micky Hulse

unread,
Feb 19, 2015, 3:47:48 AM2/19/15
to django...@googlegroups.com
Hi,

I was just curious if anyone could give me tips on how to migrate an
FK to M2M whist retaining the FK selected data?

Long story short, I've played around with adding adding a M2M field
with a `related_name`, migrating, deleting FK, then re-naming the M2M
and removing `related_name`, but I eventually lose the data towards
the end of the hoop jumping. I think I need to get my hands dirty and
modify the schema migrations.

I've found a few (older) posts detailing the steps using South (for
example, [1]), but I'm using Django's built-in migration tools …

Questions:

Should South tutorials directly relate to Django's schema migrations?

Anyone out there have a step-by-step for Django 1.7.x (using native
schema migrations) that I could follow? :)

Thanks in advance!

Cheers,
M

[1] <http://blog.klymyshyn.com/2010/12/django-model-migrations-with-south-how.html>

Andrew Pinkham

unread,
Feb 19, 2015, 4:57:16 AM2/19/15
to django...@googlegroups.com
Hi Micky,
When I had to migrate FK->M2M, I found that hand-hacking a migration file was the way to go. I wrote a multiple operation migration class that did the following:

1. create a M2M, nullable field, and set all defaults to null
2. use RunPython to run a function which takes the data from the FK field, and connects the objects in the M2M relation (bonus: create a function that does the opposite, to make this script totally reversible!)
3. remove the FK field
4. make the M2M field non-null (if desirable)

If you want the fields to be the same name, I think the safest bet is to prepend a step to the list above:

0. change name on FK field to temporary name

But I can't remember why I think that's better than changing the M2M field at the end.

I would share the code, but I can't find it at the moment. Sorry about that.

Hope that's helpful,
Andrew

Micky Hulse

unread,
Feb 19, 2015, 5:14:51 AM2/19/15
to django...@googlegroups.com
Hi Andrew, many thanks for the quick reply and help! :)

On Wed, Feb 18, 2015 at 8:56 PM, Andrew Pinkham <m...@andrewsforge.com> wrote:
> When I had to migrate FK->M2M, I found that hand-hacking a migration file was the way to go. I wrote a multiple operation migration class that did the following:
> ...<snip>...
> Hope that's helpful,

Yes, very helpful! Thanks for the tips. That gives me a great outline
and starting/ending points to shoot for.

I'll post back my code to the group if all works out and I have
something worth sharing. ;)

Thanks again Andrew!

Cheers,
Micky

Tom Evans

unread,
Feb 19, 2015, 5:55:47 PM2/19/15
to django...@googlegroups.com
On Thu, Feb 19, 2015 at 4:56 AM, Andrew Pinkham <m...@andrewsforge.com> wrote:
> Hi Micky,
> When I had to migrate FK->M2M, I found that hand-hacking a migration file was the way to go. I wrote a multiple operation migration class that did the following:
>
> 1. create a M2M, nullable field, and set all defaults to null

An M2M link between two models is created by inserting a row in to a
join table that contains a foreign key to the first model and a
foreign key to the second model. If they are not linked, there is no
row in the table with those keys.

How will either of those keys ever be null?

Django accepts the keyword argument "null" on all fields, but it is
meaningless for an M2M.

Cheers

Tom

Andrew Pinkham

unread,
Feb 19, 2015, 6:31:53 PM2/19/15
to django...@googlegroups.com
On Feb 19, 2015, at 11:54 AM, Tom Evans <teva...@googlemail.com> wrote:
> Django accepts the keyword argument "null" on all fields, but it is
> meaningless for an M2M.

That is an excellent point. That's what I get for writing this up based on memory late at night.

Sorry for the error.

Andrew

Reply all
Reply to author
Forward
0 new messages