Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#23415 closed Bug (fixed)

OneToField reference to default 'id' instead of actual primary key

Reported by: sky-chen Owned by: Markus Holtermann
Component: Migrations Version: 1.7
Severity: Release blocker Keywords:
Cc: Markus Holtermann Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by sky-chen)

Reproduce

  1. create a new project 'bug'
  2. create two app 'deg', 'pubsite'
  3. create models:
    # bug/deg/models.py
    from django.db import models
     
    # Clients
    class Client(models.Model):
        client_id = models.IntegerField('ID', primary_key=True)
        name = models.CharField('Name', max_length=255)
        short_name = models.CharField('Short name', max_length=35)
     
        class Meta:
            managed = False
            db_table = 'Clients'
            verbose_name = 'Client'
     
     
    # bug/pubsite/models.py
    from django.db import models
    from django.contrib.auth.models import User
    from deg.models import Client
     
    class Account(models.Model):
        user        = models.OneToOneField(User)
        deg_client  = models.OneToOneField(Client)
  1. make migrations
  2. check sqlmigrate pubsite 0001
BEGIN;

CREATE TABLE `pubsite_account` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `deg_client_id` integer NOT NULL UNIQUE, `user_id` integer NOT NULL UNIQUE);
ALTER TABLE `pubsite_account` ADD CONSTRAINT pubsite_account_deg_client_id_1b7724045f4a7977_fk_Clients_id FOREIGN KEY (`deg_client_id`) REFERENCES `Clients` (`id`);
ALTER TABLE `pubsite_account` ADD CONSTRAINT pubsite_account_user_id_3d5e7937e7fad36_fk_auth_user_id FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);

COMMIT;

Change History (7)

comment:1 Changed 5 years ago by Markus Holtermann

Cc: Markus Holtermann added
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

Some details that are causing the problem: The migration 0001 for deg.Client has a CreateModel operation that adds the Client model to Django's migration state. Unfortunately the operation doesn't contain any fields:

        migrations.CreateModel(
            name='Client',
            fields=[],
            options={
                'managed': False,
                'db_table': 'Clients',
                'verbose_name': 'Client',
            },
            bases=(models.Model,),
        ),

Therefore Django doesn't know about the explicit primary key field and cannot point the FK their but rather relies on some defaults. The problem is in django.db.migrations.autodetector.MigrationAutodetector.generate_created_unmanaged() and .generate_created_proxies() and which makes proxy models also be affected by that bug.

Right now this problem can be worked around with the following steps:

  1. remove existing migrations for dep and pubsite
  2. change managed = False to managed = True
  3. run manage.py makemigrations dep pubsite
  4. change managed = True back to managed = False
  5. in dep.migrations.0001_initial add 'managed': False as a new option to the options argument of the CreateModel operation.

comment:2 Changed 5 years ago by sky-chen

Description: modified (diff)

comment:3 Changed 5 years ago by Markus Holtermann

Owner: changed from nobody to Markus Holtermann
Status: newassigned

comment:4 Changed 5 years ago by Markus Holtermann

Has patch: set

comment:5 Changed 5 years ago by Tim Graham

Severity: NormalRelease blocker

comment:6 Changed 5 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In 215aa4f53b6bbd07d5c1eecfa94e7fcd00da813e:

Fixed #23415 -- Added fields for unmanaged and proxy model migrations.

Thanks sky-chen for the report.

comment:7 Changed 5 years ago by Tim Graham <timograham@…>

In 00c2a721e20f6487571ed14b69aed620f474104c:

[1.7.x] Fixed #23415 -- Added fields for unmanaged and proxy model migrations.

Thanks sky-chen for the report.

Backport of 215aa4f53b from master

Note: See TracTickets for help on using tickets.
Back to Top