我正在使用SQLAlchemy-0.7.8创建一个Pyramid应用程序。我使用的是64位Python3.2。
问题是,为什么以下函数没有向数据库提交任何内容?
def create_card(sText,sCard):
"""
create a wildcard instance if all is well (ie,sCard match in sText)
return
oCard, dCard
otherwise return False,False
"""
oMatch = re.search(sCard,sText)
if oMatch:
oCard = WildCard()
#set up some stuff about the WildCard
DBSession.add(oCard)
DBSession.flush()
dCard = {
'id' : oCard.id,
'span' : oMatch.span(),
'card' : oCard.card_string,
}
return oCard,dCard
return False,False
我从另一个脚本导入DBSession。它的定义如下:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
以下是一些背景信息:
我正在制作的应用程序用于通过使用正则表达式来表征大块HTML。如果应用程序卡住并且认为应该为一段文本匹配wilcard,那么将为用户提供一个小表格来填写。一旦表单被提交,就会调用create_card。如果通配符与字符串匹配,则会创建WildCard实例。
WildCard类没什么特别的,它只存储一个字符串和一些整数。如果我打印出dCard,看起来WildCard已经成功提交,因为它有一个整数id。如果我没有在数据库会话上调用flush,则dCard ['id']为None。
id字段如下:
id = Column(Integer,Sequence('wild_seq'), primary_key=True)
添加和刷新行会导致以下控制台输出:
2012-09-16 12:30:34,845 INFO [sqlalchemy.engine.base.Engine][Dummy-2] INSERT INTO wildcard_wildcards (card_string, range_id, brand_id, category_id, group_cat_map_id, heading_group_id, heading_to_grp_map_id, heading_id, value_map_id, igneore_match) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2012-09-16 12:30:34,845 INFO [sqlalchemy.engine.base.Engine][Dummy-2] ('sCard contents', None, None, None, None, None, None, None, None, 0)
所以直到这一点,一切都表现得很好。
这是问题所在: 即使WildCard实例看起来已经提交到数据库,并且没有引发异常,直接检查数据库显示没有进行任何更改。
用commit()替换flush()会引发以下异常:
AssertionError: Transaction must be committed using the transaction manager
答案 0 :(得分:24)
您需要提交您的交易。
您可以显式地执行此操作(通过调用DBSession.commit()
或使用pyramid_tm
middleware;后者会在成功响应时自动提交事务(使用2xx HTTP响应)。
如果您对会话制作者使用ZopeTransactionExtension
扩展名,则后者仅为SQLAlchemy提交交易:
from zope.sqlalchemy import ZopeTransactionExtension
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
如果您已经在使用ZopeTransactionExtension
并希望显式提交事务,则需要使用transaction
包:
导入交易
transaction.commit()