使用会话查询方法实例化SQLAlchemy Base对象

时间:2011-06-14 23:14:29

标签: python sqlalchemy

以下是我的SQLAlchemy模型的最简单描述:

Host对象(Base的子类)和Network对象(也是Base)。主机与网络具有1:多的关系,并且与主机关联的网络对象可以直接与主机对象的信息一起识别,作为其启动的一部分。 (即主机的__init__()提供了所有必要的信息,以便能够通过SQLAlchemy会话找到网络对象。

我正在考虑的是将sqlalchemy会话传递给Host对象,以便Host.__init__()可以查询数据库并找到正确的Network对象,即

new_host = Host(sqlalchemy_sb_session, ip_address)

并直接在__init__()中建立关联。这对我来说似乎非常难看,但我想不出任何其他方法让Host对象能够将自己与Network对象相关联。

我知道这会奏效,但必须有更好的方法。别人怎么解决这个问题?

1 个答案:

答案 0 :(得分: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())