2012-03-31 47 views
4

我有一個Django應用程序,它從各種來源收集有關作曲家(音樂意義上的)信息 - API,HTTP POST,刮等等上。如何在Django中處理數據更正(但這不是Django特有的!)

一旦這個信息被彙總,它不是很高的質量。所以你可能在一個地方有「J S Bach」,在另一個地方有「J. S。Bach」,還有其他各種錯誤。這導致我的表中有幾行代表同一個人。

我想通過製作「J. S. Bach」的規範版來消除這些重複,並且讓它如此以至於如果我們看到「J S Bach」,我們就知道要糾正它。在現實中,有很多變化,但我很樂意將修正過程作爲人工輸入的手動修正過程。

所以我的問題是,在代碼中表示這個最好的方法是什麼?此刻,我的模型是:

class Composer(models.Model): 
    name = models.CharField(max_length=100) 

我應該:

  • 有一個新的ComposerCorrection模式,即映射到composer_idcanonical_id
  • 添加可選canonical_idComposer型號?
  • 其他一些我沒有考慮過的事情?

另外值得一提的是,有其他關係,涉及的作曲家,如Work屬於Composer。當糾正發生時,這些ID也需要以某種方式重新指出,但我認爲這不是主要問題的一部分。

讓我知道你是否想要更多的信息!

+0

你需要更好地指定給你什麼糾正手段。如果數據庫中存在重複,是否足以消除它?你似乎暗示你想創建一個鏈接到正確的條目,這是爲什麼?是否有關於作曲家的新信息只存在於命名錯誤的db行中? – vascop 2012-03-31 14:44:05

+0

你說得對,我不應該保留那些古老的作曲家信息。我想創建一個鏈接到正確的條目,以便我可以在將來執行更正 - 就像拼寫檢查一樣。因此,如果我再次遇到「J S Bach」,應用程序現在可以確定它應該是「J. S。Bach」。它導致更加整潔的數據。 – 2012-03-31 17:33:52

+1

你可能想要考慮拆分和合並:假設你有一大堆「J. C. Bach」的作品,但是後來有人意識到其中一半是Johann Christian,另一半是Johann Christoph。 – 2012-03-31 18:33:53

回答

2

添加到VascoP's answer(我會想辦法讓這個cmoment但在它有點太多代碼),你可以存儲自己replace_dic在數據庫中,以便您可以通過例如添加更正Django管理員,而不必更改任何代碼。這可能是這樣的:

class ComposerCorrection(models.Model): 
    wrong_name = models.CharField(max_length=100, unique=True) 
    canonical_name = models.CharField(max_length=100) 

def correct_name(name): 
    try: 
     return ComposerCorrection.objects.get(wrong_name=name).canonical_name 
    except ComposerCorrection.DoesNotExist: 
     return name 

然後你就可以把correct_nameComposersave()方法(或預保存信號),也可以增加VascoP的correctComposer功能作爲後保存信號ComposerCorrection對象,所以增加一個新的將修復數據庫,而無需做其他任何事情。

+0

這是一個很好的數據庫版本。我在代碼中使用dic的理由是,在db版本中,每次插入時都會打db來搜索更正。儘管如此,您的版本確實可以更好地管理更正。 – vascop 2012-03-31 18:53:22

+0

@VascoP對,這是一個權衡。哪一個更好取決於用例。 – Dougal 2012-03-31 19:34:09

-1

如果Composer在完成數據收集之前僅包含名稱,爲了簡單起見,我可以選擇不首先將Composer名稱規範爲Composer,而是直接將它們存儲在Work實例中。就像

class Work(models.Model): 
    composer_name = models.CharField(max_length=100) 
    ... 

然後手動過濾作者名稱,並在Work的admin更改列表中執行批量更新,w/help和filter。

然後,您可以創建Composer實例和鏈接工作實例給他們,甚至使用composer_name作爲作曲家的主鍵..

+0

請評論投票原因,從而可以做出一些改進。我認爲簡單的扁平結構對於任務來說是直接的,不管以後會採用哪種修正或集羣過程。 – okm 2012-04-01 01:00:24

1

當你發現一個錯誤命名作曲您應該更新這些關係並刪除錯誤命名Composer

def correctComposer(canonical_composer_name, wrong_composer_name): 
    canonical_composer = Composer.objects.get(name__exact=canonical_composer_name) 
    wrong_composer = Composer.objects.get(name__exact=wrong_composer_name) 

    # repeat this for each relationship 
    work = wrong_composer.work_set.all() 
    for entry in work: 
    entry.composer = canonical_composer 

    correction.save() 

    wrong_composer.delete() 

編輯:這適用於以前插入作曲家。爲了在插入時自動校正,可以使用不同的方法,因爲如果已經有適合他的規範作曲家,我們不需要創建新的作曲家。

對於這一點,你可以保持一個字典(應保持模型的可讀性附近)的頻繁失誤和correcNames功能:

replace_dic = { 
    'motzart' : 'Mozart', 
    'j s bach' : 'J. S. Bach' 
    } 

def correctNames(name, dic): 
    return dic.get(name.lower(), name) 

通過使鍵小寫你不區分大小寫的替代這是一種的獎金。

然後你可能會覆蓋Composer保存方法是這樣的:

def save(self, *args, **kwargs): 
    self.name = correctNames(self.name, replace_dic) 
    super(Composer, self).save() 
+0

謝謝 - 你的答案的前半部分是真棒(所以+1!),但下半年不是我想要的。我想我有一個單獨的模型存儲校正映射的想法,即「Motzart」(字符串)應映射到規範的「Mozart」(Composer外鍵)。 – 2012-03-31 17:36:04

+0

嗯,你確實讓我們猜測你的用例,但是這個映射到插入時自動更正與映射不同,或者你更喜歡在錯誤插入後運行自動更正? – vascop 2012-03-31 17:40:16

+0

我的意思不是很重要,如果我的問題不清楚,我很抱歉。這個想法是,修正發生在任何插入之前。 – 2012-03-31 17:46:22