2013-02-25 61 views
0

我得到一個錯誤,我不enum1.py實例化多AbstractConcreteBase問題

class Enum1(MyEnum): 
    years = Column(SmallInteger, default=0) 

# class MyEnums1: 
# NONE = Enum1() 
# Y1 = Enum1(years=1) 

在enum2.py與AbstractConcreteBase

瞭解my_enum.py

class MyEnum(AbstractConcreteBase, Base): 
    pass 

class Enum2(MyEnum): 
    class_name_python = Column(String(50)) 

in test.py

from galileo.copernicus.basic_enum.enum1 import Enum1 
from galileo.copernicus.basic_enum.enum2 import Enum2 
#... 

如果我取消註釋enum1.py中的三行,則在第二次導入時出現以下錯誤。

AttributeError的:對象類型「MyEnum」有沒有屬性「

但沒有MyEnums1它的工作原理在正常工作一個單獨的文件罰款,或MyEnums1。爲什麼這個實例會影響導入?無論如何,我可以保持MyEnums1在同一個文件中?

回答

2

abstractconcretebase的目的是將非標準操作順序應用於標準映射過程。通常,映射是這樣的:

  1. 定義一個類被映射
  2. 定義一個表
  3. 類映射到表使用映射器()。

聲明式本質上結合了這三個步驟,但這就是它的作用。

當使用一個抽象的具體基地,我們有這個需要發生的完全特殊的步驟 - 基類需要被映射到子類映射到的所有表的聯合。因此,如果你有enum1和enum2,那麼「Base」需要映射到本質上「select * from enum1 UNION ALL select * from enum2」。

這種映射到UNION不可能零碎髮生; MyEnum基類必須將每個子表的全部UNION一次呈現給mapper()。所以AbstractConcreteBase執行復雜的任務,重新安排聲明性工作的方式,直到mapper configuration發生時,基本MyEnum根本不會被映射,其中一些地方會在您首次實例化映射類時出現。然後將其自身作爲所有現有映射子類的映射基礎插入。

因此,基本上通過在類級別實例化一個Enum1()對象,就像調用configure_mappers()方式太早一樣,這樣到Enum2()出現時,abstractconcretebase就會被烘焙並且進程失敗。

所有這一切,在類級別實例化像Enum1()這樣的映射類是完全正確的。 ORM映射的對象與全局對象完全相反,並且必須始終在特定會話的本地創建。

編輯:這些類應該有{「具體」:真}在他們這是你爲什麼得到這個消息的一部分。我試圖看看消息是否可以改進。

編輯2:是的,這裏的機制很奇怪。我已經提交了其他一些可以跳過這個特定錯誤信息的東西,儘管現在它會以不同的方式出現並且好多了。如果讓這種失敗更加優雅,需要更多的工作。

+0

非常明確的解釋謝謝。 – rhaskett 2013-02-26 17:26:17