Tuesday, November 29, 2016

How to add AutoField to/switch out primary key for an existing table?

A model was designed with a wrong assumption of uniqueness and given a
natural key. We now need to switch to a surrogate primary key.
Upgrading Django is currently not an option. The production database
may not be dropped/restored for this, it is in use by several
unrelated projects (remember the time before apis and microservices,
the time of really monolithic databases?)

This is for a project started before Django 1.0, currently running on
Django 1.7.

How do I migrate from here:

(assetname was thought unique on its own)

class MoveAssetToOrg(models.Model):
assetname = models.CharField(max_length=64, primary_key=True)
org = models.ForeignKey(Org)

class FreeSubscription(models.Model):
..
moved_assets = models.ManyToManyField(MoveAssetToOrg)

class PaidSubscription(models.Model):
..
moved_assets = models.ManyToManyField(MoveAssetToOrg)

to here?

(assetname is unique together with org)

class MoveAssetToOrg(models.Model):
id = models.AutoField(primary_key=True)
assetname = models.CharField(max_length=64)
org = models.ForeignKey(Org)

class Meta:
unique_together = ('assetname', 'org')

class FreeSubscription(models.Model):
..
moved_assets = models.ManyToManyField(MoveAssetToOrg)

class PaidSubscription(models.Model):
..
moved_assets = models.ManyToManyField(MoveAssetToOrg)

(Merging free and paid subscription is in the works but is not as time
sensitive.)

There are only a handful of entries in MoveAssetToOrg, and several
thousands in (Free|Paid)Subscription. Fortunately, there aren't any
other apps with knowledge of MoveAssetToOrg. It used to be the case
that assets were rarely moved, this is no longer the case.

I have considered using a fake composite key instead of a sequence,
with the key a string composite of assetname and org.id:

class MoveAssetToOrg(models.Model):
id = models.CharField(max_length=128, primary_key=True)
assetname = models.CharField(max_length=64)
org = models.ForeignKey(Org)

class Meta:
unique_together = ('assetname', 'org')

I have no good idea on how to do this with the migrations system either.


--
HM

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACQ%3Drrd-oM-RyBxsT-7f0U3HQXnde2SSQo7RMc%3DfwVzAnXKvYA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment