association_proxy创建者中的会话

时间:2012-06-22 09:22:07

标签: python sqlalchemy

我使用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。

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

2 个答案:

答案 0 :(得分:0)

这个问题在SQLAlchemy 0.7中也存在。我在稍微不同的背景下遇到了同样的问题。由于associationproxy是一个 Python描述符,并且描述符在类级别上运行,因此您无法为创建者函数提供对绑定方法的引用(在实例级别上操作)。

我到达了以下解决方案:

  1. 在您的创建者函数中,从全局会话制作者创建新会话并获取对象
  2. 从此临时会话中立即删除您提取的对象
  3. 关闭会话
  4. 返回您的对象
  5. 我的代码如下所示:

    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
    

答案 1 :(得分:0)

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

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