我已經將一些度量標準事件導入到Django項目中。接下來,我將事件分組爲會話,將其定義爲給定時間窗口內的一系列連續事件。使用django-south運行數據遷移時出現「no such column」錯誤
我的models.py如下:
from django.db import models
from django.contrib.auth.models import User
class Event(models.Model):
name = models.CharField(max_length=255, blank=True, db_index=True)
id1 = models.CharField(max_length=255, blank=True, db_index=True)
id2 = models.CharField(max_length=255, blank=True)
time = models.DateTimeField(db_index=True)
user = models.ForeignKey(User, related_name='events', null=True, db_index=True)
session = models.ForeignKey('Session', related_name='events', null=True, db_index=True)
def __unicode__(self):
return '"%s" event' % self.name or 'unnamed'
class Session(models.Model):
user = models.ForeignKey(User, related_name='sessions', null=True)
我現在想這些非規範化會話的開始和結束時間,以避免不得不做的所有工作階段的事件MAX和MIN聚合。所以我的新會話模型看起來像這樣。
class Session(models.Model):
user = models.ForeignKey(User, related_name='sessions', null=True)
start = models.DateTimeField(db_index=True, null=True)
end = models.DateTimeField(db_index=True, null=True)
我已經添加字段,創建的模式遷移(其運行正常),並創建了一個數據遷移:
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
"Write your forwards methods here."
orm.Session.objects \
.annotate(
start_time=models.Min('events__time'),
end_time=models.Max('events__time')) \
.update(start=models.F('start_time'), end=models.F('end_time'))
def backwards(self, orm):
"Write your backwards methods here."
pass
models = {
'auth.group': {
...
'metrics_import.event': {
'Meta': {'object_name': 'Event'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'id1': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'id2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'session': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'events'", 'null': 'True', 'to': "orm['metrics_import.Session']"}),
'time': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'events'", 'null': 'True', 'to': "orm['auth.User']"})
},
'metrics_import.session': {
'Meta': {'object_name': 'Session'},
'end': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'start': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sessions'", 'null': 'True', 'to': "orm['auth.User']"})
}
}
似乎很簡單,但運行數據遷移給出:
django.db.utils.DatabaseError: no such column: metrics_import_event.time
我檢查,列呢,其實,存在的,無論是從Django的外殼:
>>> Event.objects.all()[0].time
datetime.datetime(2012, 1, 19, 3, 0, 3)
,並直接在DB模式:
sqlite> .schema metrics_import_event
CREATE TABLE "metrics_import_event" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(255) NOT NULL,
"id1" varchar(255) NOT NULL,
"id2" varchar(255) NOT NULL,
"time" datetime NOT NULL,
"user_id" integer REFERENCES "auth_user" ("id"),
"session_id" integer
);
CREATE INDEX "metrics_import_event_3a04cc98" ON "metrics_import_event" ("time");
CREATE INDEX "metrics_import_event_52094d6e" ON "metrics_import_event" ("name");
CREATE INDEX "metrics_import_event_6b4dc4c3" ON "metrics_import_event" ("session_id");
CREATE INDEX "metrics_import_event_fbfc09f1" ON "metrics_import_event" ("user_id");
我敢肯定有一些愚蠢的我錯過了,但無法弄清楚什麼。
謝謝!
編輯:請注意,最初的架構遷移與--fake
應用中,不知怎的,重要情況。
你說你之前運行過--fake遷移 - 你列出的樣本來自運行最終遷移之前的樣本嗎? – Alvin 2012-07-03 18:05:44
@Alvin是的,我用--fake運行了初始遷移,因爲我已經用syncdb創建了初始表。我展示的SQL輸出是在遷移運行之前(它不能運行,因爲它失敗 - 因此問題:) – 2012-07-11 19:26:15
您是否嘗試運行一個分析器來查看生成的查詢是什麼?好奇,如果時間欄被包裹在'時間',以避免擊中保留字? – Alvin 2012-07-11 20:41:11