2011-06-14 67 views
0

實例化的SQLAlchemy的基本對象這裏是我的SQLAlchemy模型的簡單描述:與會話查詢方法

主機對象(基本的子類),和網絡對象(也庫)。主機與網絡具有1:多關係,並且與主機相關聯的網絡對象可以作爲其初始化的一部分直接標識給主機對象的信息。 (即主機的__init__()與所有必要的信息提供給能夠找到網絡對象與SQLAlchemy的會議。

我正在考慮這樣做是對的SQLAlchemy會話傳遞到主機對象,以便Host.__init__()可以查詢數據庫並找到正確的網絡對象,即

new_host = Host(sqlalchemy_sb_session, ip_address) 

並直接在__init__()的關聯。這似乎很醜陋給我,但我想不出任何其他方式,將主機對象能夠將其自身關聯到網絡對象。

我知道這會起作用,但必須有更好的方法。其他人如何解決這個問題?

回答

3

我會避免將Session對象傳遞給類的構造函數。
如果從主機上很容易找到網絡,您是否真的需要將關係保存在數據庫中?你可能只是有一個正確使用SA查詢來代替:

class Host(...): 
    ... 
    @property 
    def Network(self): 
     Session.object_session(self).query(Network).find(*my_search_criteria*) 

但很明顯,一些查詢僅僅是容易得多,如果你有Network對象以及必須確保它們的存在。在這種情況下,Session.object_session的技巧可以再次使用,但它不適用於尚未添加到會話中的新創建的對象。 在這種情況下,您應該可以使用SessionExtension對象。使用結構應類似於以下內容:

from sqlalchemy.orm.interfaces import SessionExtension 
class TestSessionExtension(SessionExtension): 
    def before_flush(self, session, flush_context, instances): 
     for obj in session.new: 
      if isinstance(obj, Host): 
       # if the Host has no Network object assigned, then... 
       # ... search-or-create the Network object using 'session' 
       # ... assign this network object to the Host 
Session = sessionmaker(bind=engine, extension=TestSessionExtension()) 
+0

這太棒了。我不清楚從哪裏開始查看SQLAlchemy文檔,但是您的回答給了我一些好的想法,從哪裏開始。非常感謝。 – davidr 2011-06-16 12:58:42