2017-02-17 17 views
0

经过数小时的调试,并且由于我的组织没有很多Python专业知识,我正在寻求这个社区的帮助。我无法使用SQLAchemy +金字塔将行保存到数据库中

我试图按照this tutorial的目标提交一些数据到数据库。虽然没有错误报告,我也没有保存任何行。我究竟做错了什么?

当尝试使用db2Session犯,我得到:

交易必须使用事务管理器提交。

但是在教程中没有任何地方可以看到正在使用的事务管理器。我认为这位经理绑定使用zope.sqlalchemy?然而,没有其他的事情发生。再次帮助将非常感激!

我在我的主要功能如下设置在金字塔应用:

from sqlalchemy import engine_from_config 
from .models import db1Session, db2Session 

def main(global_config, **settings): 
""" This function returns a Pyramid WSGI application. 
""" 
    db1_engine = engine_from_config(settings, 'db1.') 
    db2_engine = engine_from_config(settings, 'db2.') 

    db1Session.configure(bind=db1_engine) 
    db2Session.configure(bind=db2_engine) 

在.models/__ init__py,我有:

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import (scoped_session, sessionmaker) 
from zope.sqlalchemy import ZopeTransactionExtension 

db1Session = scoped_session(sessionmaker(
    extension=ZopeTransactionExtension())) 
db2Session =  
    scoped_session(sessionmaker(extension=ZopeTransactionExtension())) 

Base = declarative_base() 

在./model/db2.py我有:

class PlateWellResult(Base): 
    __tablename__ = 'SomeTable' 
    __table_args__ = {"schema": 'some_schema'} 

    id = Column("ID", Integer, primary_key=True) 
    plate_id = Column("PlateID", Integer) 
    hit_group_id = Column("HitID", Integer, ForeignKey(
     'some_schema.HitGroupID.ID')) 
    well_loc = Column("WellLocation", String) 

我的保存功能的相关位看起来像这样。 ./lib/db2_api.py:

def save_selected_rows(input_data, selected_rows, hit_group_id): 
    """ Wrapper method for saving selected rows """ 
    # Assume I have all the right data below. 
    new_hit_row = PlateWellResult(
     plate_id=master_plate_id, 
     hit_group_id=hit_group_id, 
     well_loc=selected_df_row.masterWellLocation) 

    db1Session.add(new_hit_row) 
    # When I try the row below: 
    # db2Session.commit() 
    # I get: Transaction must be committed using the transaction manager 
    # If I cancel the line above, nothing gets committed. 
    return 'Save successful.' 

这个函数是从我的浏览器名为:

@view_config(route_name='some_routename', renderer='json', 
      permission='create_hit_group') 
def save_to_hitgroup(self): 
    """ Backend to AJAX call to save selected rows to a hit_group """ 
    try: 
     # Assume that all values were checked and all the right 
     # parameters are passed 
     status = save_selected_rows(some_result, 
            selected_rows_list, 
            hitgroup_id) 
     json_resp = json.dumps({'errors': [], 
           'status': status}) 
     return json_resp 
    except Exception as e: 
     json_resp = json.dumps({'errors': ['Error during saving. {' 
              '0}'.format(e)], 
           'status': []}) 
     return json_resp 
+0

如果您搜索链接为“事务”的页面,则有一行使用事务管理器:'with transaction.manager:'。就我个人而言,我避免了这种令人费解的全局变量或伪全局变量。我为每个请求创建自己的“会话”更加快乐。 – jpmc26

+0

您是否使用了每个请求事务管理包['pyramid_tm'](http://docs.pylonsproject.org/projects/pyramid_tm/en/latest/)?如果没有,那么你没有做任何事情。您也可以像上一篇文章中指出的那样明确地使用事务管理器。 –

+0

哦,如果你添加它,那么记得在你的异常处理程序中手动处理'transaction.doom()'或'transaction.abort()',因为你抓住了所有的东西。 –

回答

1

以上说法都不错。我只想在这里总结一下。

事务管理器由pyramid_tm开始/提交/中止。如果你不使用它,那很可能是问题所在。

您还在压缩可能需要传送给事务管理器的数据库异常。您可以通过异常处理程序中的transaction.abort()来完成此操作。

相关问题