我看过以前有类似问题的人的例子,但是我似乎不明白为什么我的例子不能工作,因为我使用的是同一个会话。
这是我的代码块,它只是查询数据库以查看客户是否存在,然后在另一个插入中使用该客户。但是,一旦我到达线,transaction.commit(),它抛出DetachedInstanceError。这可能来自于另一种方法中的早期transaction.commit()吗?
@view_config(route_name='create_location', renderer='templates/main.html')
def create_location(request):
#get the json data from the ajax call
data = request.json_body
session = DBSession
locationName = data["location"]
custID = data["custID"]
Customer = session.query(TCustomer).filter(TCustomer.ixCustomer==custID).one()
#create customer
Location = TLocation(sDescription=locationName, ixCustomer=Customer)
session.add(Location)
session.flush()
transaction.commit()
return Response('ok')这是我的DBSession:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))发布于 2014-05-30 19:35:53
以下是解决办法:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(keep_session=True)))必须添加keep_session=True
然后,我所要做的不是做session = DBSession(),而是在查询和会话工作中使用DBSession
发布于 2014-05-31 18:53:29
这可能来自于另一个方法中的早期transaction.commit()吗?
是的,,如果在同一个请求-响应周期内调用另一个方法,那么一旦事务提交,SQLAlchemy就不能保证任何内存中的ORM对象仍然代表数据库的实际状态,所以您不能只在一个事务中获取一个对象并将它保存回另一个事务中,而不显式地将现在分离的对象合并到一个新会话中。
您通常不应该在代码中使用transaction.commit() 。使用ZopeTransactionExtension的思想是,它将SQLAlchemy事务与金字塔的请求-响应周期联系起来--在请求启动时构造一个新会话,如果请求成功或回滚,则在请求失败时提交(即在您的视图中引发异常)。在您的代码中,您不应该担心提交任何内容--只需将新对象添加到会话中:
@view_config(route_name='create_location', renderer='templates/main.html')
def create_location(request):
#get the json data from the ajax call
data = request.json_body
customer = DBSession.query(Customer).filter(Customer.id==data["custID"]).one()
session.add(Location(description=data["location"], customer=customer))
return Response('ok')(忍不住让代码更像“普通”Python代码.匈牙利符号是..。呃..。现在不太常用..。(谢谢你给我一个怀旧的闪回:))(详见http://legacy.python.org/dev/peps/pep-0008/ )。
在罕见的情况下,您可能希望请求的某些部分无论如何都成功,甚至只有在发生错误时才希望将数据保存到数据库(对数据库的日志错误可能是一个例子)。在这些情况下,您使用了一个单独的会话,它是在没有ZopeTransactionExtension的情况下配置的。您需要手动提交这样的会话:
try:
do_something_which_might_fail()
except Exception as e:
session = ErrorLogSession()
session.add(SomeORMObject(message=format_exception(e))
session.commit()进一步读:
dev wikipage_add()函数。https://stackoverflow.com/questions/23961871
复制相似问题