Ticket #420 (closed defect: fixed)
Field ordering wrong after running an initial schema migration
| Reported by: | jklaiho | Owned by: | andrew |
|---|---|---|---|
| Priority: | major | Milestone: | 0.7.1 |
| Component: | commands | Version: | 0.7 |
| Keywords: | field ordering initial schemamigration | Cc: |
Description
#145 dealt with incorrect field ordering, and was fixed quite a long time ago.
Since upgrading to South 0.7, we've been running into what seems to be the same problem, though manifesting itself in a different way.
Here's a sample model definition, a simple newsletter model:
email = models.EmailField(unique=True)
name = models.CharField(max_length=100, blank=True)
date_added = models.DateTimeField(blank=True, null=True, editable=False)
date_modified = models.DateTimeField(blank=True, null=True, editable=False)
posts_received = models.PositiveIntegerField(default=0, editable=False)
Here's the frozen model definition produced for it by a schemamigration command with the --initial parameter:
models = {
'simplenewsletter.recipient': {
'Meta': {'object_name': 'Recipient'},
'date_added': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'date_modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'posts_received': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
}
}
It looks like the frozen fields are listed in alphabetical order instead of the model order. Doesn't seem right, but may be intentional. But the real weirdness is the field ordering as produced by running that migration:
posts_received name date_modified email date_added id
The final ordering doesn't correspond to either the way it's set in the model, or the frozen dictionary in the migration.
This is very inconvenient when using GUI tools like Sequel Pro to browse and administer the database. Often-crucial id fields may be practically anywhere and not the first in the list of fields, as they are supposed to (and were with South 0.6). "Less-important" fields being in the wrong order is also a hassle when trying to locate things.
We're using MySQL 5.1.37, the pre-1.2 trunk version of Django and database collation utf8_swedish_ci.
Attachments
Change History
comment:2 Changed 3 years ago by brian@…
BaseChanges? class is using a regular dict instead of a SortedDict?().
I fixed it as following,
On /south/creator/changes.py
from django.utils.datastructures import SortedDict?
class BaseChanges?(object):
def split_model_def(self, model, model_def):
real_fields = SortedDict?()
meta = SortedDict?()
m2m_fields = SortedDict?()
comment:3 Changed 3 years ago by brian@…
I got few other errors if I use SortedDict? on the meta dict. I guess I should use Sorted Dict on real_fields only.
Thanks,
comment:4 Changed 3 years ago by andrew
- Status changed from new to assigned
Marked #455 as a dupe of this.
comment:5 Changed 3 years ago by andrew
- Status changed from assigned to closed
- Resolution set to fixed
Seems to have been fixed at some point since this was reported. My subconscious is clearly better at bugtrackers than me.

Ahh, I see where the final ordering comes from, it's in the actual table creation command in the migration:
db.create_table('simplenewsletter_recipient', ( ('posts_received', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), ('name', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)), ('date_modified', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), ('email', self.gf('django.db.models.fields.EmailField')(unique=True, max_length=75)), ('date_added', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ))Still, the fields listed in that command don't correspond to the actual model or the frozen version as listed in the ticket.