2012-06-22 30 views
2

我使用SQLAlchemy 0.5和Python 2.6.6。session_proxy创建者

我想在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。

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

+0

如果以异步方式编程(例如Tornado),情况也是如此。在龙卷风会议永远不会是全球性的,以免交易会被不同的处理程序混淆。 –

回答

0

此问题在SQLAlchemy 0.7中仍然存在。我在一个稍微不同的环境中遇到了同样的问题。因为associationproxy是一个Python描述符并且描述符在类级别上操作,所以您不能为创建者函数提供对绑定方法(对实例级别进行操作)的引用。

我得出了以下解决方案:

  1. 您制作功能中,从全球sessionmaker从这个临时会话立即创建一个新的会话,并获取你的对象
  2. EXPUNGE您获取的对象
  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 
0

我想你需要的是一个validate方法:

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

+0

@v = value.value @的用途是什么? – Timur