2

我使用 SQLAlchemy 0.5 和 Python 2.6.6。

我想在 Association_proxy 的创建者中选择或创建一个引用对象。我的问题是,我需要一个会话,但我不知道在创建者回调中从哪里得到它。

如何在其关联代理的创建者之一中使用对象所属的会话?

我尝试过的方法不起作用

我找到了session.object_session,但回调中没有任何对象,除非它是我的 ORM 对象的一部分。如果它是我的对象的一部分,则调用者将不会作为方法调用(第一个参数是代理的值,而不是对象的引用):

class Event(ManagerBase):

    # If association_proxy calls this, 'self' is the key, not the
    # reference to the calling instance.
    def _field_find_or_create(self, key, val):
        session = session.object_session(self)
        field = session.query(Field).filter_by(name=key).first()
        if not field:
            field = Field(name=key)

        return EventFieldValue(field=field, value=val)

    fields = association_proxy("field_values", "value",
                               creator=_field_find_or_create)

我可以将对象本身传递给创建者函数吗?在这种情况下,我可以在这个对象上调用 object_session。

我的项目使用了几个会话,因此我必须确定创建者执行的具体会话。

4

2 回答 2

1

我认为您需要的是一种验证方法:

from sqlalchemy.orm import validates, object_session

class Event(ManagerBase):
   value = relationship(FieldValue)    
   fields = association_proxy("field_values", "value",
                              creator=lambda group: FieldValue(value=value))

   @validates("field_values") 
   def _validate_field_values(self, key, value): 
       session = object_session(self) 
       if session is not None: 
           v = value.value 
           with session.no_autoflush: 
               uvalue = session.query(FieldValue) \ 
                   .filter_by(name=a) \ 
                   .first() 
               if uvalue: 
                   session.expunge(value) 
                   return ugroup 
       return value

学分转到https://groups.google.com/forum/#!topic/sqlalchemy/RMDI1SnGhd0

于 2014-08-05T08:39:10.317 回答
0

这个问题在 SQLAlchemy 0.7 中也存在。我在略有不同的情况下遇到了同样的问题。因为关联代理是Python 描述符,并且描述符在类级别上运行,所以您不能为创建者函数提供对绑定方法(在实例级别上运行)的引用。

我得出了以下解决方案:

  1. 在您的创建者函数中,从全局会话创建者创建一个新会话并获取您的对象
  2. 立即从此临时会话中删除您获取的对象
  3. 关闭会话
  4. 归还你的物品

我的代码如下所示:

def find_object(name):                                                                                                                                                                                    
    # Because we can't get a grip on the actual session we instead use a global
    # session for querying this instance.
    session = Session()
    obj = Model.query(session).filter_by(name=name).first()
    # We also have to dump the reference to that session, so the created object
    # can be used on other sessions.
    session.expunge(obj)
    # We don't need that session any more.
    session.close()
    return obj
于 2012-09-27T15:04:39.303 回答