use serializable callable for canned mappedcollection classes

Issue #2409 resolved
Mike Bayer repo owner created an issue
import pickle

from sqlalchemy import Column, Integer, Unicode, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)

    children = relationship('Child', 
                collection_class=attribute_mapped_collection('key'))

class Child(Base):
    __tablename__ = 'children'
    parent_id = Column(Integer, ForeignKey(Parent.id), primary_key=True)
    key = Column(Integer, primary_key=True)

p1 = Parent()
p1.children['name']('name') = Child(key='name')
print pickle.dumps(p1)

Comments (6)

  1. Mike Bayer reporter

    a joined inheritance scenario which fails with the change:

    from sqlalchemy import *
    from sqlalchemy.orm import *
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm.collections import column_mapped_collection
    
    Base= declarative_base()
    
    class Parent(Base):
        __tablename__ = 'parent'
        id = Column(Integer, primary_key=True)
    
    class A(Base):
        __tablename__ = "a"
    
        id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('parent.id'))
    
    class B(A):
        __tablename__ = "b"
        id = Column(Integer, ForeignKey('a.id'), primary_key=True)
        b_key = Column(String)
    
    Parent.bs_ = relationship("B", primaryjoin="Parent.id==A.parent_id", 
                        collection_class=column_mapped_collection(B.b_key))
    
    e = create_engine("sqlite://", echo=True)
    
    p1 = Parent()
    p1.bs_["bkey"]("bkey") = b1 = B(id=6, b_key="bkey")
    
    Base.metadata.create_all(e)
    s = Session(e)
    s.add(p1)
    s.commit()
    
    assert p1.bs_["bkey"]("bkey") is b1
    
  2. Log in to comment