1

I have model AAA with UUID as primary key. Many models have relation to this model.

Now I want to migrate them to use Slug as this primary key, to keep slug value in database as a reference.

What will be the correct way to do that?

Thinking that this might be some multi-step migration. But having many tables that reference to AAA would like to avoid blocking whole db for much time or any other issues in production.

from django.db import models
from django_extensions.db.fields import AutoSlugField
from model_utils.models import UUIDModel


# Django models example
class AAA(models.Model):
    id = UUIDField(primary_key=True, version=4, editable=False)
    title = models.CharField(max_length=255, unique=True)
    slug = AutoSlugField(populate_from='title', primary_key=False)


class BBB(models.Model):
    aaa = models.ForeignKey(AAA, on_delete=models.CASCADE)
    # ... other fields here ...
wowkin2
  • 5,895
  • 5
  • 23
  • 66
  • Probably a [bad idea to begin with](https://stackoverflow.com/a/338424/5747944) but simply flipping the `primary_key` keyword arguments should _work_. I'm not sure if migration time is an easily avoidable issue. Keep in mind also it's possible for your slug field to have collisions even if the slug is populated from a unique field, so double check that your current data for the `slug` column is actually unique (for example the slug for the titles `hello-world`, `hello world!` and `hello world` are all the same!) – sytech Aug 08 '22 at 19:11
  • @sytech I know that this is not good idea and rare case to do. But I have only few dozens of slugs which are manually created and I'll need to rely on them as they will be in another microservice. And want to distinquish values visually inside this service. – wowkin2 Aug 08 '22 at 19:20
  • If you just want to use a different field in the URLs, you can implement that without changing your database models (though you probably want to at least index the field for performance). In any case, if you don't have much data, the migration should be quick. Have you tried just setting `primary_key=True` for your `slug` field (and setting `primary_key=False` for your `id` field) and running migrations? – sytech Aug 08 '22 at 19:26
  • It says that `django.db.utils.ProgrammingError: multiple primary keys for table "aaas" are not allowed`. Probably that because `makemigrations` also doesn't see change for `id`, only slug and doesn't add it to operations. But I believe that there is a need to migrate data in "child" tables. – wowkin2 Aug 08 '22 at 19:34
  • Okay, yeah I see the problem pretty clearly now. [This might help you](https://stackoverflow.com/q/2055784/5747944) but seems more trouble than it's worth. I'm guessing you probably would need to create an entirely new table (model) with the appropriate keying you want, migrate, re-create data in the new table, then update all the foreign key references to point to the new table (probably requires some manual migration code), migrate again, then delete the old table and migrate a final time. – sytech Aug 08 '22 at 19:50
  • 1
    Hope that no :) I saw that answer, and still looking for another options. – wowkin2 Aug 08 '22 at 19:51

0 Answers0