AttributeError: 'NoneType' object has no attribute '_sa_instance_state'

280 views
Skip to first unread message

Erik Dahl

unread,
Apr 23, 2013, 1:00:46 PM4/23/13
to sqlalche...@googlegroups.com
I have a pickle attribute on a class that sometimes (not sure exactly why) causes this exception when loading the object.
 
  pgh = self.env.db.query(PolicyGroupsHistory).order_by(desc('created_on')).first()
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2156, in first
    ret = list(self[0:1])
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2023, in __getitem__
    return list(res)
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2348, in instances
    rows = [process[0](row, None) for row in fetch]
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/mapper.py", line 2115, in _instance
    populate_state(state, dict_, row, isnew, only_load_props)
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/mapper.py", line 1969, in populate_state
    populator(state, dict_, row)
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/strategies.py", line 150, in fetch_col
    dict_[key] = row[col]
  File "build/bdist.linux-x86_64/egg/sqlalchemy/types.py", line 2043, in process
    return loads(value)
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/state.py", line 193, in __setstate__
    manager.setup_instance(inst, self)
  File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/instrumentation.py", line 286, in setup_instance
    state or self._state_constructor(instance, self))
AttributeError: 'NoneType' object has no attribute '_sa_instance_state'

I found that in sqlalchemy/orm/state.py:190 there is the following:

        # setup _sa_instance_state ahead of time so that
        # unpickle events can access the object normally.
        # see [ticket:2362]
        manager.setup_instance(inst, self)
        manager.dispatch.unpickle(self, state)

inst is None when setup_instance is called causing it to blow up.  I took the call out and everything works fine.  At the top of __setstate__ is the following:

        inst = state['instance']
        if inst is not None:
            self.obj = weakref.ref(inst, self._cleanup)
            self.class_ = inst.__class__
        else:
            # None being possible here generally new as of 0.7.4
            # due to storage of state in "parents".  "class_"
            # also new.
            self.obj = None
            self.class_ = state['class_']

which seems to say that it's ok for inst to be None.  Thoughts?

-EAD

Michael Bayer

unread,
Apr 23, 2013, 1:27:22 PM4/23/13
to sqlalche...@googlegroups.com
On Apr 23, 2013, at 1:00 PM, Erik Dahl <ed...@erikdahl.org> wrote:

I have a pickle attribute on a class that sometimes (not sure exactly why) causes this exception when loading the object.
 

I found that in sqlalchemy/orm/state.py:190 there is the following:

        # setup _sa_instance_state ahead of time so that
        # unpickle events can access the object normally.
        # see [ticket:2362]
        manager.setup_instance(inst, self)
        manager.dispatch.unpickle(self, state)

inst is None when setup_instance is called causing it to blow up.  I took the call out and everything works fine.  At the top of __setstate__ is the following:

        inst = state['instance']
        if inst is not None:
            self.obj = weakref.ref(inst, self._cleanup)
            self.class_ = inst.__class__
        else:
            # None being possible here generally new as of 0.7.4
            # due to storage of state in "parents".  "class_"
            # also new.
            self.obj = None
            self.class_ = state['class_']

which seems to say that it's ok for inst to be None.  Thoughts?

the call is there for the benefit of events, so it should at least be a conditional.  This change is in r05be37c8b931.   The error is likely the product of your pickle process finding objects that have already been garbage collected (the InstanceState remains in scope longer than the object itself), which might mean you're pickling dirty objects, or something like that.   

Putting ORM-mapped objects into a binary column with PickleType is not such a great idea overall.  Really, PickleType itself is a bad idea in almost every case, since pickles aren't very portable, use a lot of memory, aren't secure, are slow, and have lots of bugs.  


Erik Dahl

unread,
Apr 23, 2013, 2:54:34 PM4/23/13
to sqlalche...@googlegroups.com
On Tuesday, April 23, 2013 1:27:22 PM UTC-4, Michael Bayer wrote:

the call is there for the benefit of events, so it should at least be a conditional.  This change is in r05be37c8b931.   The error is likely the product of your pickle process finding objects that have already been garbage collected (the InstanceState remains in scope longer than the object itself), which might mean you're pickling dirty objects, or something like that.   

Putting ORM-mapped objects into a binary column with PickleType is not such a great idea overall.  Really, PickleType itself is a bad idea in almost every case, since pickles aren't very portable, use a lot of memory, aren't secure, are slow, and have lots of bugs.  

Totally agree that pickling is generally bad and especially pickling ORM mapped objects.  The pickle only has fundamental types, no objects.  I've checked this over several times because I was worried that an object was sneaking in to the pickle.  Is there another potential explanation?

-EAD
Reply all
Reply to author
Forward
0 new messages