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

68 views
Skip to first unread message

Hanne Moa

unread,
Nov 29, 2016, 7:27:37 AM11/29/16
to django...@googlegroups.com
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
Reply all
Reply to author
Forward
0 new messages