问题
When I inspect the Trac database I get:
class TicketChange(models.Model):
ticket = models.IntegerField()
time = models.BigIntegerField()
author = models.TextField(blank=True)
field = models.TextField()
oldvalue = models.TextField(blank=True)
newvalue = models.TextField(blank=True)
class Meta:
managed = False
db_table = 'ticket_change'
With not primary key:
>>> TicketChange.objects.all()
DatabaseError: column ticket_change.id does not exist
LINE 1: SELECT "ticket_change"."id", "ticket_change"."ticket", "tick...
Because I need to specify a pk but the original primary key of ticket_change
in Trac is:
Primary key (ticket, time, field)
But It's not possible in Django: Django Multi-Column Primary Key Discussion.
If I define time
like pk I can't add two tickets changes in the same time.
What can I do?
回答1:
You're right. It's a known problem. So the only solutions are hacks (sort of).
Your best option is to use django-compositepks. The drawbacks are that it doesn't really support model relationships, so you will not be able to navigate to any relationship from your composite-pk model. However, looking at your TicketChange model this doesn't seem like an issue (unless you have more models with relationships to this one).
Another option would be to manually add the id column (and make sure to apply any additional changes to the db), thereby creating the new one-column primary key. A third option (and what I would probably do), pretty similar to the last one but cleaner, would be to create a new database from scratch and then populate it with a script by fetching the data from your existing legacy db.
Sorry I don't have any better solution for you, that's the way it is. Legacy dbs and django are always a headache, have gone through some similar processes myself. Hope this helps!
回答2:
This is a use case the Django ORM simply does not support. If you're able to modify the database schema, add an additional column that will serve as the primary key for Django: An integer field with AUTO_INCREMENT (MySQL) or a SERIAL (PostgreSQL). It shouldn't desturb your other applications using the table since it will be managed by your database when new records are inserted. You can still use the actual primary key when making queries through the ORM:
ticket_change = TicketChange.objects.get(ticket=1234, time=5678, field='myfield')
来源:https://stackoverflow.com/questions/19999465/django-custom-primary-key