2012-06-27 39 views
0

我正在尋找一種方法來管理一套Python數據結構,這將非常適合關係架構,但沒有真正的數據庫或解析SQL的開銷。可以假定數據量足夠小,以方便地適應內存(比如,沒有結構包含超過一百萬個元素)。Python數據結構的外鍵約束,而不使用真正的數據庫

最重要的是,我想自動執行外鍵約束。觸發外鍵約束違規的斷言失敗就足夠了;這總是一個編程錯誤。

下面是我想要完成的一個真實世界的例子。我確實有這樣做的代碼,但沒有自動外鍵約束檢查它容易出錯和亂七八糟的斷言。

(這些是數據結構,用於代碼分析的機器代碼程序的執行軌跡,爲好奇。記錄器節目輸出每個獨特(previous_instruction_addr,current_instruction_addr,stack_pointer_change)元組一次。)

  • instrs :set(int)(看到機器指令的地址)
  • next_instrs:dict(int - > set(int)),映射指令(必須在instrs中)的字典到一組指令(所有這些指令都必須在instrs)。相關地,instrs×instrs的子集。
  • stk_changes:字典((INT,INT) - >組(INT)),一個字典映射對指令(其中,對指示必須在next_instrs)到一組中的堆棧指針寄存器的變化的
  • jumps:set((int,int)),被認爲是從一條指令跳轉到另一條指令的跳轉(包括函數調用或函數返回)的子集。其實我現在將它作爲兩個字符來實現,因爲我需要能夠同時查詢「這個指令在哪裏跳轉?」的形式。和「什麼指令跳到這個指令?」。
  • calls:set((int,int)),作爲函數調用的jumps的子集。
  • rets:set((int,int)),是從函數返回的jumps的子集。
  • basic_blocks:set(int),instrs的子集;的基本塊第一地址(代碼塊,其中執行永遠只能開始在第一個指令,即沒有跳轉到中間,永遠只在最後一個指令結尾,即沒有從中間跳)
  • containing_bb: dict(int - > int),它是包含每條指令的基本塊。子集instrs×basic_blocks
  • functions:set(int),基本塊被認爲是函數的開始。 basic_blocks的子集。
  • function_calls_by_bb:dict(int - > int),由基本塊調用的函數;子集basic_blocks×functions

等等;你明白了。

什麼,我基本上是尋找的是管理所有這種結構,並自動執行所有的外鍵約束的方式;例如,我想basic_blocks.add(something)失敗,一個錯誤,如果something不是instrs成員。同樣,我想如果basic_blocks.remove(something)something仍然function_calls_by_bb簡稱失敗。顯然,在add()remove()方法所有這些結構的書寫斷言是不必要的冗長且容易出錯相比,在一個SQL數據庫模式,例如,外鍵約束。

我目前正在和sqlalchemy一起使用內存中的sqlite數據庫,它可以讓我以一種很好的方式描述約束,但我理想的是尋找更輕量級的東西,而不涉及數據庫引擎。 (這可能是一個數據庫引擎是最終做我正在做的事情的正確方法,但我目前正在評估替代品。)

另外,如果你能想到的其他方式來管理結構,如此,我也有興趣聽到這些。

回答

2

使用SQLite。無需安裝服務器,並免費獲得外鍵約束。如果這是一對錶的問題,那麼您可以對檢查進行硬編碼,但正如您發現的那樣,當您必須重新實現DBMS的設計目標時,它會失控。