2017-02-17 4 views
0

시간이 지나면 디버깅을하고 조직에 많은 Python 지식이 없기 때문에이 커뮤니티에 도움을 요청하고 있습니다.SQLAchemy + Pyramid를 사용하여 DB에 행을 저장할 수 없습니다

일부 데이터를 데이터베이스에 커밋한다는 목표로 this tutorial을 따르려고합니다. 오류가보고되지는 않지만 행을 저장하지 않습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? db2Session를 사용하여 커밋하려고 할 때

, 내가 얻을 :

트랜잭션은 트랜잭션 관리자를 사용하여 최선을 다하고해야합니다.

그러나 튜토리얼 어디에도 트랜잭션 관리자가 사용되는 것을 볼 수 없습니다. 나는이 관리자가 zope.sqlalchemy를 사용하여 바인딩되어 있다고 생각했습니다. 그러나, 아무것도 일어나지 않고있다. 다시 도움을 주시면 감사하겠습니다!

나는이 피라미드 앱 내 주요 기능에 다음과 같은 설정 : .models에서

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) 

/__ 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 I에서 have :

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()을 통해이 작업을 수행 할 수 있습니다.