我想弄清楚如何構建一個Django過濾器,其中包含依賴於MySQL中定義的用戶定義函數(UDF)的術語。如何在Django中使用MySQL用戶定義函數(UDF)?
我的UDF處理稱爲化學信息學的計算化學分支。其中一個函數(oe_matches)讓我測試子結構(表示爲「SMARTS」字符串)是否匹配結構(表示爲「SMILES」字符串)。您可以將它們視爲與同一個字符串匹配的正則表達式同構。
在我的數據庫中有一個名爲「節點」的主題表。這包含有關研究主題的可搜索文本。該主題中的一些信息涉及分子。我有一張分子表。分子可以在多個主題,而主題可以是關於一個以上的分子,所以我有:
class Node(models.Model):
title = models.CharField()
content = models.CharField()
class Structure(models.Model):
smiles = models.CharField(max_length=255)
nodes = models.ManyToManyField(Node)
現在我想搜索具有「測試」在標題或內容的所有節點,和,其與SMARTS模式「[C;!H0]」(即,具有至少一個氫的碳)匹配。
理想我想寫這類似如下:
q = ((models.Q(title__icontains="test") |
models.Q(content__icontains="test")
).filter(models.Q(structure__node_smiles = oe_match(smarts="[C;!H0]")))
)
其中oe_match是一些東西,知道如何爲MySQL的右後端代碼,在這種情況下,「oe_match(「[C; !H0]「,Structure.smiles)',並且Django在這裏看到結構_node_smiles,並執行其多對多的魔法來使這些部分結合在一起。
我看到,我能得到我想要的東西與原料()接口(模數小的語法錯誤和使用錯誤的連接類型):
SELECT * FROM Node, Node_Structure, Structure WHERE
((Node.title LIKE "%test%" OR Node.content LIKE "%test%") AND
(Node.id = Node_Structure.node AND
Node_Structure.structure = Structure.id) AND
oe_matches("[C;!H0]", Structure.smiles));
我寧願不混合和匹配我的數據庫這樣的圖層。另外,我將不得不做一些代碼重組。 (目前我創建了一個過濾器,我稍後傳遞給模型進行搜索)。
長期來看,我希望其他人使用我的MySQL UDF進行化學信息學,並且我認爲某些高級別Django調用了我的潛在的用戶(除了與我合作的其他兩個用戶之外)是好的,所以即使我能用raw()解決眼前的問題,我仍然想知道長期的高級解決方案。