DetachedInstanceError:实例<TCustomer at 0x428ddf0>未绑定到会话

2024-10-17 06:20:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经看过以前有类似问题的人的例子,但是我似乎不明白为什么我的问题不能解决,因为我使用的是同一个会话。在

这是我的代码块,它简单地查询数据库以查看是否存在客户,然后在另一个insert中使用该客户。但是当我一碰到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')

这是我的演讲:

^{pr2}$

Tags: thejsondata客户requestsessioncreatelocation
2条回答

解决方案如下:

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(keep_session=True)))

必须添加keep_session=True

然后我不用做session = DBSession()我只需要使用DBSession进行查询和会话工作

Could this be from an earlier transaction.commit() in another method?

是,如果在同一请求-响应周期内调用另一个方法-一旦提交事务,SQLAlchemy无法保证内存中的ORM对象仍然代表数据库的实际状态,因此,如果不显式地将现在分离的对象合并到新的会话中,就不能在一个事务中获取对象并将其保存回另一个事务中。在

您通常不应该在代码中使用transaction.commit()使用ZopeTransactionExtension背后的想法是它将SQLAlchemy事务与Pyramid的请求-响应周期联系在一起-当请求启动时,将构造一个新的会话,如果请求在视图中提交失败,则返回。在代码中,您不应该关心提交任何内容—只需将新对象添加到会话中:

@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代码。。。匈牙利符号是。。。呃。。。现在不是很常用。。。谢谢你给了我一个怀旧的闪回:))见PEP 8详情)。

很少的情况下,您可能希望请求的某些部分成功,或者甚至只在发生错误时才将数据保存到数据库(例如,将错误记录到数据库中)。在这些情况下,您将使用一个单独的会话,该会话没有配置ZopeTransactionExtension。您需要手动提交此类会话:

^{pr2}$

进一步阅读:

  • When do I construct a Session, when do I commit it, and when do I close it?-SQLAlchemy文档中的高级概述。”TL;DR:一般来说,将会话的生命周期与访问和/或操作数据库数据的函数和对象分开并在外部进行。”请注意,金字塔已经为您完成了所有的会话管理—独立于代码的外部结束。

  • Databases Using SQLAlchemy-一个使用SQLAlchemy的基本金字塔应用程序。请参见dev wikipage_add()函数,以获取将一些数据保存到数据库的典型代码的示例。

相关问题 更多 >