Hi Mike,

Thanks for the quick response.  If that's the intended behaviour I'll go 
back to non-bulk inserts for my inherited types.  Doubtless I could work 
around it by inserting N new Entities, fetching their autoincrement ID's 
then using them to make Child1 and Child2's but I don't trust myself with 
the added complexity.


Cheers,
Alex.



On Monday, February 29, 2016 at 10:38:22 PM UTC, Alex Hewson wrote:
>
> Hello All,
>
> I'm trying to use the new bulk_save_objects() to improve performance on 
> bulk inserts, and have run into a problem.  If bulk_save_objects() is used 
> to save objects of a polymorphic class..
>
>    1. They are created correctly in the DB, with polymorphic type column 
>    populated correctly
>    2. BUT queries for the new objects will return one of incorrect type.  
>    In my case I'm getting instances of Child1 back when I would expect to get 
>    a Child2.
>    
> The following code demonstrates the problem:
>
> #!/usr/bin/env python3
> # -*- coding: utf-8 -*-
>
> from sqlalchemy import create_engine
> from sqlalchemy import Column, Integer, SmallInteger, String, ForeignKey
> from sqlalchemy.orm import sessionmaker
> from sqlalchemy.ext.declarative import declarative_base
>
> Base = declarative_base()
>
> class Entity(Base):
>   __tablename__ = 'Entity'
>   Id              = Column(Integer, primary_key=True, nullable=False)
>   Content         = Column(String)
>   _polytype       = Column(SmallInteger, nullable=False)
>
>   __mapper_args__ = {
>     'polymorphic_identity':1,
>     'polymorphic_on':_polytype
>   }
>
> class Child1(Entity):
>   __tablename__   = 'Child1'
>   MyId            = Column(ForeignKey("Entity.Id"), primary_key=True)
>   __mapper_args__ = {'polymorphic_identity':11}
>
> class Child2(Entity):
>   __tablename__   = 'Child2'
>   MyId            = Column(ForeignKey("Entity.Id"), primary_key=True)
>   __mapper_args__ = {'polymorphic_identity':12}
>
>
> if __name__ == '__main__':
>   # engine = create_engine('sqlite:///:memory:', echo=False)
>   engine = create_engine('sqlite:///test.db', echo=False)
>   Session = sessionmaker(bind=engine)
>   sess = Session()
>   Base.metadata.create_all(engine)
>   c1_many = [Child1(Content="c1inst_%d"%i) for i in range(0,1000)]
>   c2_many = [Child2(Content="c2inst_%d"%i) for i in range(0,1000)]
>   sess.bulk_save_objects(c1_many)
>   sess.bulk_save_objects(c2_many)
>   # sess.add_all(c1_many)
>   # sess.add_all(c2_many)
>   sess.flush()
>   sess.commit()
>   for c in sess.query(Child1):
>     assert isinstance(c, Child1)
>   for c in sess.query(Child2):
>     assert isinstance(c, Child2)
>
>
> All the calls to assert isinstance(c, Child1) complete successfully.  But 
> once we start checking for Child2 - boom, we are still getting back Child1 
> instances.
>
> At first I wondered if I was misunderstanding SA's implementation of 
> polymorphism, so tried inserting rows the traditional way with 
> sess.add_all().  But that works fine so I think I've exposed a bug in the 
> new bulk_save_objects() code.
>
> My environment is Python 3.5.1, SQLAlchemy==1.0.12, SQLite 3.8.10.2 on OSX.
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to