我有一个与此question非常相似的问题,但是,即使我尝试做类似的事情
...
from my_app.models import Session
user = Session.merge(user)
new_foo = models.Foo(user=user)
...
我基本上从请求中获取用户模型对象并尝试创建与用户有关系的新Foo
对象,但它失败了DetachedInstanceError
,因为(我认为)我正在使用的event.listens
稍后会使用其他Session
。
我的监听器功能如下所示:
@event.listens_for(mapper, 'init')
def auto_add(target, args, kwargs):
Session.add(target)
Session
定义为:
Session = scoped_session(sessionmaker())
如果我依靠event.listens
将目标添加到Session
,我怎样才能确保处理添加到请求上下文的用户之类的对象?
允许我完成这项工作的一件事就是用sessionmaker
调用expire_on_commit=False
,但我认为这不是我应该做的(按照令人敬畏的SQLA文档):
commit()的另一个行为是默认情况下它会在提交完成后使所有实例的状态到期。这使得当下次访问实例时,通过属性访问或者它们存在于查询结果集中,>他们收到了最近的州。要禁用此行为,请使用>配置sessionmaker。
expire_on_commit=False
。
我想拥有用户对象的最新状态。我有什么选择在正确的地方处理merge
?
实际回溯(特定于Web框架的特定行修剪)如下所示:
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
发生这种情况的实际方法是:
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/')
上面的问题是你看到我从请求上下文中获取User
对象,并且发生在另一个Session
中(或者至少,这是我假设发生的事情)
__repr__
的使用导致了我的问题,在请求期间的某个时刻,正在调用模型的字符串表示,并且我的模型的这一部分让我遇到麻烦:
def __repr__(self):
return '<User %r>' % self.username
如果我没有实现该方法,那么我之前所拥有的一切都按预期工作。我该怎么做才能防止这种提升?#/ p>
答案 0 :(得分:0)
当我使用sqlalchemy运行nosetest时,我看到了同样的错误。
在我的例子中,logging.getLogger('foo')。debug('data%s',mydata)发生了这个错误。 'mydata'是sqlalchemy映射的实例,但尚未提交。我的解决方法是logging.getLogger('foo').debug('data %s', repr(mydata))
您可以更改__repr__
方法,以便找出问题吗?
def __repr__(self):
try:
return '<User %r>' % self.username
except:
return 'I got it!'