2012-03-02 110 views
2

我已經將一些度量標準事件導入到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應用中,不知怎的,重要情況。

+0

你說你之前運行過--fake遷移 - 你列出的樣本來自運行最終遷移之前的樣本嗎? – Alvin 2012-07-03 18:05:44

+0

@Alvin是的,我用--fake運行了初始遷移,因爲我已經用syncdb創建了初始表。我展示的SQL輸出是在遷移運行之前(它不能運行,因爲它失敗 - 因此問題:) – 2012-07-11 19:26:15

+0

您是否嘗試運行一個分析器來查看生成的查詢是什麼?好奇,如果時間欄被包裹在'時間',以避免擊中保留字? – Alvin 2012-07-11 20:41:11

回答

0

請注意,您正在嘗試運行更新聲明與連接 - 我敢肯定,這不被Sqlite支持;也就是說,它可能使用'with'子句來實現,但我懷疑Django是這樣做的(因爲with-clause只在Django 1.6之後的版本3.8.3上增加了SQLite)。我認爲你得到的東西非常接近這個:

$ sqlite3 
SQLite version 3.8.3.1 2014-02-11 14:52:19 
Enter ".help" for instructions 
Enter SQL statements terminated with a ";" 
sqlite> create table x (a int, b int); 
sqlite> insert into x values(1,2); 
sqlite> select * from x; 
1|2 
sqlite> create table y (c int, d int); 
sqlite> update x set b = min (y.d); 
Error: no such column: y.d 

我想你可以設置登錄了它在執行之前打印所有SQL,這樣你可以得到更多的信息。

(這個回答猜測,實際上,這與南方無關 - 問題在於Django)。

相關問題