2013-08-20 7 views
7

मेरे वर्तमान मॉडल उपयोगकर्ता में, मेरे पास एक फ़ील्ड "नाम" है जो शून्य नहीं हो सकता है।स्क्लेक्लेमी के लेन-देन में त्रुटियां उचित ट्रेसबैक नहीं लौटती हैं (पायथन 2.7)

मैं उपयोगकर्ता ऑब्जेक्ट बनाने का प्रयास करता हूं, और इसे पिरामिड द्वारा प्रदान किए गए डीबीएसशन में जोड़ता हूं और इसे लेनदेन के साथ प्रस्तुत करता हूं।

with transaction.manager: 
    u = models.User() 
    models.DBSession.add(u) 

जो लोग पिरामिड का प्रयोग नहीं करते के लिए, DBSession है:

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

अब, मेरी लेनदेन में ऊपर, मैं एक मान्यता मुद्दा है - मैं उपयोगकर्ता को नाम निर्दिष्ट करने की जरूरत है, लेकिन मैंने नहीं किया हालांकि, बजाय मुझे बता एक त्रुटि होने का "आप अपने उपयोगकर्ता नाम निर्दिष्ट कर जरूरत है!", मैं इस मिल:

<ipython-input-5-47d9c0e393f7> in <module>() 
     2  u = models.User() 
----> 3  models.DBSession.add(u) 
     4 

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_manager.pyc in __exit__(self, t, v, tb) 
    118  def __exit__(self, t, v, tb): 
    119   if v is None: 
--> 120    self.commit() 
    121   else: 
    122    self.abort() 

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_manager.pyc in commit(self) 
    109   """ See ITransactionManager. 
    110   """ 
--> 111   return self.get().commit() 
    112 
    113  def abort(self): 

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_transaction.py in commit(self) 
    276    tb = None 
    277    try: 
--> 278     t, v, tb = self._saveAndGetCommitishError() 
    279     self._callAfterCommitHooks(status=False) 
    280     reraise(t, v, tb) 

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_transaction.py in _saveAndGetCommitishError(self) 
    300    import pdb 
    301    pdb.set_trace() 
--> 302    traceback.print_stack(sys._getframe(1), None, ft) 
    303    # Append the stack entries from here down to the exception. 
    304    traceback.print_tb(tb, None, ft) 

/usr/lib/python2.7/traceback.py in print_stack(f, limit, file) 
    267   except ZeroDivisionError: 
    268    f = sys.exc_info()[2].tb_frame.f_back 
--> 269  print_list(extract_stack(f, limit), file) 
    270 
    271 def format_stack(f=None, limit=None): 

/usr/lib/python2.7/traceback.py in print_list(extracted_list, file) 
    23    ' File "%s", line %d, in %s' % (filename,lineno,name)) 
    24   if line: 
---> 25    _print(file, ' %s' % line.strip()) 
    26 
    27 def format_list(extracted_list): 

/usr/lib/python2.7/traceback.py in _print(file, str, terminator) 
    11 
    12 def _print(file, str='', terminator='\n'): 
---> 13  file.write(str+terminator) 
    14 
    15 

TypeError: 'unicode' does not have the buffer interface 

मैं हाथ में समस्या मिली है कहीं न कहीं, वहाँ एक अजगर संस्करण 2 है वह यह है कि बनाम 3 असंगतता, यहां दिखाया गया TypeError: 'str' does not support the buffer interface। मुझे पता है कि स्क्लाक्लेमी पायथन 3+ का समर्थन करता है, और यही वह जगह है जहां से समस्या आ रही है।

ध्यान दें कि यदि मैं अपना लेनदेन सही तरीके से करता हूं, तो कोई त्रुटि नहीं फेंक दी जाती है।

क्या इस मुद्दे को traceback.py में कोड ओवरराइट किए बिना प्राप्त करने का कोई तरीका है?

+0

क्या आप त्रुटि को पुन: उत्पन्न करने के लिए पूर्ण कोड प्रदान कर सकते हैं? – javex

+0

मुझे यकीन नहीं है कि आपको और क्या देखना है। उपयोगकर्ता मॉडल में केवल कुछ SQLAlchemy कॉलम हैं, और ऐसा लगता है कि त्रुटियों को सही तरीके से संभालने में असमर्थता से असंबंधित है (यह उन सभी मॉडलों के लिए हुआ जो मैंने कोशिश की थी, लेकिन केवल कुछ कॉलम के लिए अमान्य प्रविष्टियों के साथ प्रतिबद्ध करने की कोशिश करते समय) – limasxgoesto0

+2

क्या आप एक नए वर्चुअलएव में त्रुटि को पुन: उत्पन्न करने के लिए न्यूनतम कोड और आवश्यकता फ़ाइल प्रदान कर सकते हैं? –

उत्तर

2

जो त्रुटि आप देख रहे हैं वह है (कम से कम सीधे) SQLAlchemy के कारण नहीं है, बल्कि इसके बजाय SQLAlchemy, IPython के संयोजन और जिस तरह से आप transaction का उपयोग करने का प्रयास कर रहे हैं। यदि आप इन उपकरणों के अनुशंसित उपयोग का पालन करते हैं तो यह दूर हो जाएगा।

अस्वीकरण: नीचे दिए गए स्कोप्ड सत्र और ज़्रोपट्रांसएक्शन एक्सटेंशन का उपयोग पिरामिड में करने का अनुशंसित तरीका नहीं है, लेकिन मैं जितना संभव हो सके आपके प्रदत्त कोड के साथ चिपकना चाहता हूं।

एक फ़ाइल में इस रखो और एक virtualenv से चलाने के SQLAlchemy स्थापित और आप SQLAlchemy से सही त्रुटि संदेश दिखाई देगा: आप को आग तो sqlalchemy.exc.IntegrityError: (IntegrityError) NOT NULL constraint failed: user.name u'INSERT INTO user DEFAULT VALUES'()

:

from sqlalchemy import types 
from sqlalchemy import create_engine 
from sqlalchemy.schema import Column 
from zope.sqlalchemy import ZopeTransactionExtension 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import sessionmaker, scoped_session 

Base = declarative_base() 


class User(Base): 
    __tablename__ = 'user' 
    name = Column(types.String, primary_key=True) 


def pretend_view(request): 
    """Pretend view in a Pyramid application using pyramid_tm""" 
    import transaction 
    user = User() 
    with transaction.manager: 
     DBSession.add(user) 
    return user 

if __name__ == '__main__': 
    engine = create_engine('sqlite://') 
    global DBSession 
    DBSession = scoped_session(
     sessionmaker(extension=ZopeTransactionExtension())) 
    DBSession.configure(bind=engine) 
    Base.metadata.bind = engine 
    Base.metadata.create_all() 
    #import IPython; IPython.embed() 
    pretend_view("dummy request") 

इस अपवाद उत्पन्न करता है इसके बजाय IPython और pretend_view चलाएं, आपको उल्लिखित यूनिकोड त्रुटि प्राप्त होगी।

pyramid_tm

अब का उचित उपयोग, यदि आप IPython में सही त्रुटि संदेश देखना चाहते हैं, "सही ढंग से" सत्र का उपयोग करें!

आमतौर पर transaction का उपयोग आपके कोड में स्पष्ट रूप से करने का कोई कारण नहीं है; जब दृश्य स्वचालित रूप से लौटाता है (मानते हैं कि कोई अपवाद नहीं उठाया जाता है) pyramid_tm लेनदेन करेगा।यह दृश्य को चलाने के लिए उचित तरीके से हो सकता है, और यहां तक ​​कि IPython के भीतर से सही अपवाद उत्पन्न करेगा:

def pretend_view(request): 
    """Pretend view in a Pyramid application using pyramid_tm""" 
    session = DBSession() 
    user = User() 
    session.add(user) 
    session.flush() 
    import transaction 
    transaction.commit() 
    return user 

:

def pretend_view(request): 
    """Pretend view in a Pyramid application using pyramid_tm""" 
    session = DBSession() # You're using a sessionmaker, so you should make a session! 
    user = User() 
    session.add(user) 
    session.flush() 
    return user 

यदि आप वास्तव में दृश्य के भीतर से लेन-देन के लिए प्रतिबद्ध करना चाहते हैं अन्य संसाधन

SQLAlchemy-पिरामिड रसोई की किताब: http://docs.pylonsproject.org/projects/pyramid/en/latest/tutorials/wiki2/index.html#bfg-sql-wiki-tutorial

pyramid_tm घ ocumentation: http://pyramid-tm.readthedocs.org/en/latest/

+0

ओह वाह, यह बहुत लंबा रहा है क्योंकि मैंने यह प्रश्न लिखा था। हम अपने कोड में लेनदेन का उपयोग नहीं करते हैं (या यदि हमने किया है, तो यह पता लगाने से पहले कि यह जेडटीई कैसे काम करता है), लेकिन हम इसका उपयोग तब करते हैं जब डेटा को pshell/ipython में छेड़छाड़ की आवश्यकता होती है। हम निश्चित रूप से हमारे किसी भी विचार में लेनदेन का उपयोग नहीं कर रहे हैं। जब हमें ipython में लेनदेन का उपयोग करने की आवश्यकता होती है, तो हम अब लेनदेन.मैनेजर पर आमतौर पर license.commit() का उपयोग करते हैं, और त्रुटि संदेश तब से कोई समस्या नहीं दे रहे हैं। – limasxgoesto0

संबंधित मुद्दे