Opened 16 years ago

Closed 16 years ago

#10010 closed (invalid)

ManyToMany programming error

Reported by: rmaciejczyk@… Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm rather newbie in the django and python programming, but I'm experienced IT guy.
I tried to define data model matching to existing database (Postgresql)
Below you can find my sample code.

class DBProduct(models.Model):
    name = models.CharField(max_length=128)
    
    class Meta:
        db_table = u'product'

class DBStore(models.Model):
    name = models.CharField(max_length=256)
    sotreproducts = models.ManyToManyField(DBProduct, through='DBStoreProducts')
        
    class Meta:
        db_table = u'singlestore'

class DBStoreProducts(models.Model):
    
    store_conf = models.ForeignKey(DBStore, db_column='store_id', primary_key=True)
    product_id = models.ForeignKey(DBProduct, primary_key=True)
    
    class Meta:
        db_table = u'storeproducts'

When I execute the following code:

    store_config = DBStore.objects.get(id=1)
    values = store_config.products.all()

I get the following Programming Error:

ProgrammingError
column storeproducts.product_id_id does not exist
LINE 1: ...product" INNER JOIN "storeproducts" ON ("product"."id" = "storeproducts...

I suppose it's related to the foreign keys configuration in the DBStoreProducts table,
since for the 'store_conf' field a database column name is defined explicitly (store_id),
but for the product_id field not. What I expected was to use a database field named the
same as 'product_id' field.

To sum up when I've changed the model and set the database column name for product id

    product_id = models.ForeignKey(DBProduct, db_column='product_id' primary_key=True)

everything seems to go smoothly, so that's obviously ManyToMany field bug.

I'm using Django 1.0.2 (stable release), Python 2.6.1 for Windows.

(BTW. All above examples have been written by hand since I needed to change my quite a secret
table names ;) Sorry for spelling mistakes)

Change History (8)

comment:1 by James Bennett, 16 years ago

Resolution: invalid
Status: newclosed

I don't see any actual description of a bug here, just the expected behavior for Django when you have a column name that doesn't match the default of the ORM.

comment:2 by rmaciejczyk@…, 16 years ago

The bug is that when you define ManyToMany intermediate table with below keys:

   store_conf = models.ForeignKey(DBStore, db_column='store_id', primary_key=True)
    product_id = models.ForeignKey(DBProduct, primary_key=True)

and for one key specify database column name, but for the other not, you get the exception
when you execute the code:

DBStore.objects.get(id=1)
values = store_config.products.all()

ProgrammingError
column storeproducts.product_id_id does not exist
LINE 1: ...product" INNER JOIN "storeproducts" ON ("product"."id" = "storeproducts...

According to the doc you don't have to define database column names for all keys and as a default value
the class field name is used, but in my example if you define the db_name for at least one field you must do it for all the rest. Otherwise the exception will occur.

comment:3 by rmaciejczyk@…, 16 years ago

Resolution: invalid
Status: closedreopened

comment:4 by Ramiro Morales, 16 years ago

The DBStoreProducts model has more than one field with primary_key option set to True. It's strange that the pre-flight validation isn't catching it.

comment:5 by rmaciejczyk@…, 16 years ago

Yes, it's done intentionally, since both these fields have been set in my database as primary key (they are unique together).

in reply to:  5 ; comment:6 by Ramiro Morales, 16 years ago

Replying to rmaciejczyk@nglogic.com:

Yes, it's done intentionally, since both these fields have been set in my database as primary key (they are unique together).

But it a unsupported configuration, see http://docs.djangoproject.com/en/dev/ref/models/fields/#primary-key

It seems there isn't a check for this in django/core/management/validation.py.

in reply to:  6 ; comment:7 by anonymous, 16 years ago

Replying to ramiro:

Replying to rmaciejczyk@nglogic.com:

Yes, it's done intentionally, since both these fields have been set in my database as primary key (they are unique together).

But it a unsupported configuration, see http://docs.djangoproject.com/en/dev/ref/models/fields/#primary-key

Ok, now I see. Thanks.

But I have the following "join" table in my database (there is no way to make a change in the table);

StoreProducts
-------------
store_id : INTEGER PK
product_id: INTEGER PK
other_field : INTEGER

See, there is no 'id' column and store_id and product_id are both primary key.
(this is a common approach in many databases according to the SQL reference).

Could you tell me how I should define my django model for this table?

in reply to:  7 comment:8 by Ramiro Morales, 16 years ago

Resolution: invalid
Status: reopenedclosed

Replying to anonymous:

See, there is no 'id' column and store_id and product_id are both primary key. (this is a common approach in many databases according to the SQL reference).

Could you tell me how I should define my django model for this table?

Given current I'd say it isn't currently possible to describe that that with Django models. At any rate it' material for django-users mailing list, closing this ticket again.

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