Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So schreiben Sie eine Migration, um den Primärschlüssel des Modells mit ManyToManyField zu ändern

Also landete ich bei SQL, um es zu beheben. Der Kern meiner Lösung ist unten - im Grunde ich

  • erstellen Sie einen Index für user_id im neuen Profil
    • Dieser Index muss existieren, bevor ich ihn als Fremdschlüssel referenzieren kann
  • eine neue Durchgangstabelle erstellen
    • Ich habe mit der Ausgabe von SHOW CREATE TABLE userprofile_userprofile_subjects begonnen (MySQL-spezifisch)
    • Ich habe die Schlüsselnamen und Beschränkungsnamen leicht geändert
  • alle Daten in die neue Durchgangstabelle kopieren
  • Lösche die alte Durchgangstabelle
  • benenne die neue Durchgangstabelle um, damit sie den Namen der alten Durchgangstabelle hat
  • Endlich die Vorgänge ausführen, die Django-Migrationen automatisch für mich generiert haben

Ich hoffe, das hilft jemand anderem. Und ich wäre immer noch daran interessiert, etwas über eine bessere Lösung zu erfahren.

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        # ...
    ]

    operations = [
        migrations.RunSQL(
            'ALTER TABLE userprofile_userprofile '
            'ADD INDEX `userprofile_userprofile_1234abcd` (user_id)'
        ),
        migrations.RunSQL (
            'CREATE TABLE userprofile_temp_table ('
            '`id` int(11) NOT NULL AUTO_INCREMENT, '
            '`userprofile_id` int(11) NOT NULL, '
            '`subject_id` int(11) NOT NULL, '
            'PRIMARY KEY (`id`), '
            'UNIQUE KEY `userprofile_userprofile_subjects_userprofile_us_7ded3060_uniq` (`userprofile_id`,`subject_id`), '
            'KEY `userprofile_userprofile_subject_1be9924f` (`userprofile_id`), '
            'KEY `userprofile_userprofile_subject_e5a9504a` (`subject_id`), '
            'CONSTRAINT `subject_id_refs_id_69796996` FOREIGN KEY (`subject_id`) REFERENCES `otherapp_subject` (`id`), '
            'CONSTRAINT `userprofile_user_id_refs_user_id_1234abcd` FOREIGN KEY (`userprofile_id`) REFERENCES `userprofile_userprofile` (`user_id`) '
            ') ENGINE=InnoDB AUTO_INCREMENT=35500 DEFAULT CHARSET=utf8 '
        ),
        migrations.RunSQL (
            'INSERT INTO userprofile_temp_table '
            '(userprofile_id, subject_id) '
            '('
            '  SELECT userprofile_userprofile.user_id, userprofile_userprofile_subjects.subject_id'
            '    FROM userprofile_userprofile_subjects'
            '    INNER JOIN userprofile_userprofile'
            '    ON userprofile_userprofile_subjects.userprofile_id ='
            '        userprofile_userprofile.id'
            ')'
        ),
        migrations.RunSQL (
            'DROP TABLE `userprofile_userprofile_subjects`'
        ),
        migrations.RunSQL (
            'RENAME TABLE `userprofile_temp_table` TO `userprofile_userprofile_subjects`'
        ),
        migrations.RemoveField(
            model_name='userprofile',
            name='id',
        ),
        migrations.AlterField(
            model_name='userprofile',
            name='user',
            field=models.OneToOneField(
                primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL
            ),
            preserve_default=True,
        ),
    ]