Opened 10 years ago

Last modified 10 years ago

#23415 closed Bug

OneToField reference to default 'id' instead of actual primary key — at Version 2

Reported by: sky-chen Owned by: nobody
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 (2)

comment:1 by Markus Holtermann, 10 years ago

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 by sky-chen, 10 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top