solving `DetachedInstanceError` with event.listens on SQLAlchemy
Question: I have a very similar problem as this
[question](http://stackoverflow.com/questions/9704927/pyramid-sql-alchemy-
detachedinstanceerror), however, even if I try to do something like

    
    
    ...
    from my_app.models import Session
    user = Session.merge(user)
    new_foo = models.Foo(user=user)
    ...
    

Where I am basically getting the user model object from the request and trying
to create a new `Foo` object that has a relation to the user, it fails with a
`DetachedInstanceError` because (I think) that the `event.listens` I am using
comes later on with a different `Session`.

My listener function looks like this:

    
    
    @event.listens_for(mapper, 'init')
    def auto_add(target, args, kwargs):
        Session.add(target)
    

And the `Session` is defined as:

    
    
    Session = scoped_session(sessionmaker())
    

If I am relying on `event.listens` to add a target to a `Session`, how could I
make sure that objects like the user, which are added to a request context be
handled?

The one thing that allowed me to make that work was to call `sessionmaker`
with `expire_on_commit=False` but I don't think that is what I should be doing
as (per the awesome SQLA docs) it:

> Another behavior of commit() is that by default it expires the state of all
> instances >present after the commit is complete. This is so that when the
> instances are next >accessed, either through attribute access or by them
> being present in a Query result set, > they receive the most recent state.
> To disable this behavior, configure sessionmaker with >
> `expire_on_commit=False`.

I want to have the most recent state of the user object. What are my options
to take care of the `merge` in the right place?

The actual traceback (web framework specific lines trimmed) looks like this:

    
    
      File "/Users/alfredo/python/my_app/my_app/models/users.py", line 31, in __repr__
        return '<User %r>' % self.username
      File "/Users/alfredo/.virtualenvs/my_app/lib/python2.7/site-packages/SQLAlchemy-0.8.0b2-py2.7-macosx-10.8-intel.egg/sqlalchemy/orm/attributes.py", line 251, in __get__
        return self.impl.get(instance_state(instance), dict_)
      File "/Users/alfredo/.virtualenvs/my_app/lib/python2.7/site-packages/SQLAlchemy-0.8.0b2-py2.7-macosx-10.8-intel.egg/sqlalchemy/orm/attributes.py", line 543, in get
        value = callable_(passive)
      File "/Users/alfredo/.virtualenvs/my_app/lib/python2.7/site-packages/SQLAlchemy-0.8.0b2-py2.7-macosx-10.8-intel.egg/sqlalchemy/orm/state.py", line 376, in __call__
        self.manager.deferred_scalar_loader(self, toload)
      File "/Users/alfredo/.virtualenvs/my_app/lib/python2.7/site-packages/SQLAlchemy-0.8.0b2-py2.7-macosx-10.8-intel.egg/sqlalchemy/orm/loading.py", line 554, in load_scalar_attributes
        (state_str(state)))
    DetachedInstanceError: Instance <User at 0x10986d1d0> is not bound to a Session; attribute refresh operation cannot proceed
    

The actual method where this takes place is this one:

    
    
    def post(self, *args, **kw):
        # Actually create one
        new_foo = Foo(user=request.context['user'], title=kw['title'], body=kw['body'])
        new_foo.flush()
        redirect('/pages/')
    

The problem above is that you see that I am fetching the `User` object from
the request context, and that happened in a different `Session` (or at least,
that is what I assume is happening).

EDIT: It seems that the use of `__repr__` is causing me issues, at some point
during the request a string representation of the model is being called and
this section of my model gets me in trouble:

    
    
    def __repr__(self):
        return '<User %r>' % self.username
    

If I don't implement that method, all that I had before works as expected.
What can I do to prevent this raising on the repr?


Answer: I saw same error when I run nosetest with sqlalchemy. In my case,
logging.getLogger('foo').debug('data %s', mydata) made this error. 'mydata' is
a sqlalchemy mapped instance but not committed yet. My workaround is
`logging.getLogger('foo').debug('data %s', repr(mydata))`

Can you change `__repr__` method as following in order to figure out your
problem?

    
    
    def __repr__(self):
        try:
            return '<User %r>' % self.username
        except:
            return 'I got it!'
    

