Reputation: 5236
I am trying to create a test database that is a replica of a preexisting database. I am using Django models (theoretically the models used with the original database) in order to do this. I recently inherited the code from someone else and am trying to figure out what exactly is going on with the code.
In the model, one the of the tables has two columns identified as the primary key.
column1 = models.IntegerField(primary_key = True)
column2 = models.IntegerField(primary_key = True)
column3 = models.CharField(max_length = 30)
When I try to sync this model to the test database - an error occurs :
File "/somePathHere/MySQLdb/connections.py", line 36, in defaulterrorhandler raise errorclass, errorvalue _mysql_exceptions.OperationalError: (1068, 'Multiple primary key defined')
It is written in the django docs that Django does not allow multiple primary keys. However, looking at the output of DESCRIBE [tablename]
in the original MySQL database, it seems like that is exactly what is going on here :
+------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| IDENTIFIER | bigint(20) | NO | PRI | NULL | |
| TIMESTAMP_ | bigint(20) | NO | PRI | NULL | |
| VALUE_ | longtext | YES | | NULL | |
+------------+------------+------+-----+---------+-------+
Note that both IDENTIFIER and TIMESTAMP_ are listed as the primary keys.
I'm seeing a lot of topics on SO ( Example 1 , Example 2, and Example 3 ) about creating a primary key based on multiple columns - is what I am seeing a composite key? In which case, how is this relayed via a Django model, i.e. how would one replicate it?
If it is not a composite key, what is it?
Upvotes: 6
Views: 8212
Reputation: 1777
It's not supported in Django, but there's a workaround. On your model specify unique_together and the fields in the Meta section:
class MyClass(models.Model):
IDENTIFIER = models.IntegerField(blank=False,null=False)
TIMESTAMP_ = models.IntegerField(blank=False,null=False)
VALUE_ = models.TextField(blank=True, null=True)
class Meta:
unique_together = ('IDENTIFIER', 'TIMESTAMP_')
This will preserve the two-column primary key behavior.
Upvotes: 4
Reputation: 424993
It's a composite primary key. Try executing this:
show create table mytable;
It should show you the definition of the composite key.
This is nothing "unusual" from a mysql perspective.
Upvotes: 2
Reputation: 56390
Django currently does not support multi-column primary keys though there are patches/forks that extend it to do so (with varying degrees of polish). From the FAQ "Do Django models support multiple column primary keys?":
No. Only single-column primary keys are supported.
But this isn't an issue in practice, because there's nothing stopping you from adding other constraints (using the
unique_together
model option or creating the constraint directly in your database), and enforcing the uniqueness at that level. Single-column primary keys are needed for things such as the admin interface to work; e.g., you need a simple way of being able to specify an object to edit or delete.
What you're seeing is not two primary keys, but rather a two-column primary key. Tables by definition can only have one primary key.
Upvotes: 3