AssertionError while pickling a result returned by query()

Issue #3738 closed
Aurelien C. created an issue

When I try to pickle the result of a query which contains deferred columns undeferred during the query with defaultload/undefer_group, pickle generates an AssertionError while trying to pickling <sqlalchemy.orm.strategy_options._UnboundLoad object> object. It still occurs when make_transient is called on this instance.

If the defaultload / undefer_group is not present there is no bug.

Here is an example which crashs from version 0.9 to 1.1.0b2:

#!/usr/bin/python
from sqlalchemy import Column, String, Integer, ForeignKey, func
from sqlalchemy.orm import deferred, relationship, joinedload, defaultload
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.orm.session import make_transient
from sqlalchemy import create_engine
import sqlalchemy
import pickle
import sys

Base = declarative_base()
engine = create_engine('sqlite:///test.sqlite')
sessionMaker = sessionmaker(bind=engine)
sessionFactory = scoped_session(sessionMaker)
session = sessionFactory()


class B(Base) :
    __tablename__ = 'b'
    id = Column(Integer, ForeignKey('a.id'), primary_key=True)
    colA = Column(String(10))
    colB = deferred(Column(String(10)), group='info')

class A(Base) :
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)
    colA = Column(String(10))
    colB = deferred(Column(String(10)))
    b = relationship(B, uselist=False)

Base.metadata.create_all(engine)
if session.query(func.count(A.id)).scalar() == 0 :
    a = A(id=1, colA='exampleA', colB='exampleB')
    b = B(colA='subExampleA', colB='subExampleB')
    a.b = b
    session.add(a)
    session.commit()


instance = session.query(A). \
    options(joinedload(A.b)). \
    options(defaultload(A.b).undefer_group('info')). \
    filter(A.id == 1).one()
make_transient(instance)
pickle.dump(instance, sys.stdout, 2)

Comments (2)

  1. Mike Bayer repo owner

    Runs fine for me. This also is Python 2 and not Python 3 as you can't write bytes to sys.stdout in py3k. I've run it with PYTHONHASHSEED=random about twenty times, no failures.

    Do you have a stack trace ? What Python interpreter is this? Can you ensure at least Python 2.7.11 as this sounds like a bug in pickle.

  2. Log in to comment