Instance is not persisted

258 views
Skip to first unread message

pkraus

unread,
Jan 3, 2012, 3:54:54 PM1/3/12
to turbo...@googlegroups.com
I have a app in production that will throw the below error about 15 times a day. No one reports a problem, no issues seem to arise because of it, and I am unable to reproduce the error on my own or on my development machine.

Obviously you don't have enough information to help me, i get that but where should i start poking around to track this down? What might cause this kind of error in an intermittent way?

TIA,
Paul

WebApp Error: <class 'sqlalchemy.exc.InvalidRequestError'>: Instance '<MultiPack at 0x2476cc6c>' is not persisted
Module weberror.errormiddleware:162 in __call__
<<              __traceback_supplement__ = Supplement, self, environ
                   sr_checker = ResponseStartChecker(start_response)
                   app_iter = self.application(environ, sr_checker)
                   return self.make_catching_iter(app_iter, environ, sr_checker)
               except:
>>  app_iter = self.application(environ, sr_checker)
Module tg.configuration:797 in remover
<<          def remover(environ, start_response):
                   try:
                       return app(environ, start_response)
                   finally:
                       log.debug("Removing DBSession from current thread")
>>  return app(environ, start_response)
Module repoze.tm:23 in __call__
<<          try:
                   result = self.application(environ, save_status_and_headers)
               except:
                   self.abort()
>>  result = self.application(environ, save_status_and_headers)
Module repoze.who.middleware:107 in __call__
<<          wrapper = StartResponseWrapper(start_response)
               app_iter = app(environ, wrapper.wrap_start_response)
      
               # The challenge decider almost(?) always needs information from the
>>  app_iter = app(environ, wrapper.wrap_start_response)
Module tw.core.middleware:43 in __call__
<<      def __call__(self, environ, start_response):
               return self.wsgi_app(environ, start_response)
      
           def wsgi_app(self, environ, start_response):
>>  return self.wsgi_app(environ, start_response)
Module tw.core.middleware:68 in wsgi_app
<<              else:
                       # Pass request downstream
                       resp = req.get_response(self.application)
                   return resp(environ, start_response)
               finally:
>>  resp = req.get_response(self.application)
Module webob.request:1053 in get_response
Module webob.request:1022 in call_application
Module tw.core.resource_injector:68 in _injector
<<      def _injector(environ, start_response):
               req = Request(environ)
               resp = req.get_response(app)
               content_type = resp.headers.get('Content-Type','text/plain').lower()
               if 'html' in content_type:
>>  resp = req.get_response(app)
Module webob.request:1053 in get_response
Module webob.request:1022 in call_application
Module beaker.middleware:73 in __call__
<<                                                     self.cache_manager)
               environ[self.environ_key] = self.cache_manager
               return self.app(environ, start_response)
>>  return self.app(environ, start_response)
Module beaker.middleware:152 in __call__
<<                          headers.append(('Set-cookie', cookie))
                   return start_response(status, headers, exc_info)
               return self.wrap_app(environ, session_start_response)
          
           def _get_session(self):
>>  return self.wrap_app(environ, session_start_response)
Module routes.middleware:131 in __call__
<<                                               r'\1', oldpath)
              
               response = self.app(environ, start_response)
              
               # Wrapped in try as in rare cases the attribute will be gone already
>>  response = self.app(environ, start_response)
Module pylons.wsgiapp:107 in __call__
<<         
               controller = self.resolve(environ, start_response)
               response = self.dispatch(controller, environ, start_response)
              
               if 'paste.testing_variables' in environ and hasattr(response,
>>  response = self.dispatch(controller, environ, start_response)
Module pylons.wsgiapp:312 in dispatch
<<          if log_debug:
                   log.debug("Calling controller class with WSGI interface")
               return controller(environ, start_response)
          
           def load_test_env(self, environ):
>>  return controller(environ, start_response)
Module pps.lib.base:31 in __call__
<<          request.identity = request.environ.get('repoze.who.identity')
               tmpl_context.identity = request.identity
               return TGController.__call__(self, environ, start_response)
>>  return TGController.__call__(self, environ, start_response)
Module pylons.controllers.core:211 in __call__
<<                  return response(environ, self.start_response)
              
               response = self._dispatch_call()
               if not start_response_called:
                   self.start_response = start_response
>>  response = self._dispatch_call()
Module pylons.controllers.core:162 in _dispatch_call
<<              req.environ['pylons.action_method'] = func
                  
                   response = self._inspect_call(func)
               else:
                   if log_debug:
>>  response = self._inspect_call(func)
Module pylons.controllers.core:105 in _inspect_call
<<                        func.__name__, args)
               try:
                   result = self._perform_call(func, args)
               except HTTPException, httpe:
                   if log_debug:
>>  result = self._perform_call(func, args)
Module tg.controllers.dispatcher:254 in _perform_call
<<          self._setup_wsgi_script_name(url_path, remainder, params)
      
               r = self._call(func, params, remainder=remainder)
      
               if hasattr(controller, '__after__'):
>>  r = self._call(func, params, remainder=remainder)
Module tg.controllers.decoratedcontroller:116 in _call
<<              params, remainder = self._remove_argspec_params_from_params(controller, params, remainder)
      
                   output = controller(*remainder, **dict(params))
      
               except formencode.api.Invalid, inv:
>>  output = controller(*remainder, **dict(params))
Module pps.controllers.secure:1217 in mp_add_order
<<              if status != 'OK':
                       if len(multipack.orders) < 1 :
                           DBSession.delete(multipack)
                           multipack = None
                       return dict(status=status,mp_id=mp_id)
>>  DBSession.delete(multipack)
Module sqlalchemy.orm.scoping:113 in do
<<  def instrument(name):
           def do(self, *args, **kwargs):
               return getattr(self.registry(), name)(*args, **kwargs)
           return do
       for meth in Session.public_methods:
>>  return getattr(self.registry(), name)(*args, **kwargs)
Module sqlalchemy.orm.session:1173 in delete
<<              raise sa_exc.InvalidRequestError(
                       "Instance '%s' is not persisted" %
                       mapperutil.state_str(state))
      
               if state in self._deleted:
>>  mapperutil.state_str(state))

Michael Pedersen

unread,
Jan 4, 2012, 12:28:25 AM1/4/12
to turbo...@googlegroups.com
Well, you're right, it's tough to give advice, especially when I've not seen that particular error.

The basics, though, would helpo: Which versions of your packages are installed? Assuming you're using a virtualenv, just get us a listing of that virtualenv's site-packages folder.

Did you build the virtualenv with --no-site-packages ?

This segment in particular looks suspicious:

Module pps.controllers.secure:1217 in mp_add_order
<<              if status != 'OK':
                       if len(multipack.orders) < 1 :
                           DBSession.delete(multipack)
                           multipack = None
                       return dict(status=status,mp_id=mp_id)
>>  DBSession.delete(multipack)

What I'm seeing here is something that looks like "I added an object, but now need to delete that object, before I've actually committed it to the database". Is that correct? If so, you might be better off creating the object, working with it, and then only adding it to the database at the end of the controller method, resulting in your getting rid of a delete() call.


--
You received this message because you are subscribed to the Google Groups "TurboGears" group.
To view this discussion on the web visit https://groups.google.com/d/msg/turbogears/-/jkKDHL4as2cJ.
To post to this group, send email to turbo...@googlegroups.com.
To unsubscribe from this group, send email to turbogears+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/turbogears?hl=en.



--
Michael J. Pedersen
My Online Resume: http://www.icelus.org/ -- Google+ http://plus.ly/pedersen
Google Talk: m.ped...@icelus.org -- Twitter: pedersentg

pkraus

unread,
Jan 4, 2012, 10:33:44 AM1/4/12
to turbo...@googlegroups.com
Thanks. I think that was it but i won't know for sure until its been running for a bit.

I thought that the way TG is setup the session (even after the add) didn't do anything until transaction was comitted (after the controller finishes).

So that ...
instance = Object()
DBSession.add(instance)
DBSession.delete(instance)

Would in fact all happen before any actual commits.


Michael Pedersen

unread,
Jan 4, 2012, 10:27:07 PM1/4/12
to turbo...@googlegroups.com
You're right, it does, but that's the problem you're experiencing (or, at least, look like you are).

Here's what happens:

transaction.begin()
DBSession.add()
DBSession.delete()
transaction.commit()

Now, the object has been added to the session, but not to the database. The delete tries to delete the object from the database (delete from tablex ...), but is unable to because the item never made it to the database.

End result is an exception.

At least, that's what it looks like from the traceback.

--
You received this message because you are subscribed to the Google Groups "TurboGears" group.
To view this discussion on the web visit https://groups.google.com/d/msg/turbogears/-/4GZ9CN4sJ30J.

To post to this group, send email to turbo...@googlegroups.com.
To unsubscribe from this group, send email to turbogears+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/turbogears?hl=en.
Reply all
Reply to author
Forward
0 new messages