On 09/12/2016 05:30 PM, 'Thomas Gillam' via sqlalchemy wrote:
Hello all,

I ran into a problem today when running delete() on a query created on a
derived polymorphic class. In a nutshell, the SQL produced from the
batch delete didn't condition on the polymorphic type, resulting in much
broader deletion than was intended. I'm running SQLAlchemy 1.0.9.

Here's a minimal example which reproduces the problem in a temporary
SQLite database, although I also observe the undesired behaviour on
Postgres.

unfortunately, the warning listed for query.update() at http://docs.sqlalchemy.org/en/latest/orm/query.html?sqlalchemy.orm.query.Query.update failed to be adapted for query.delete(), it is:

The method supports multiple table updates, as detailed in Multiple Table Updates, and this behavior does extend to support updates of joined-inheritance and other multiple table mappings. However, the join condition of an inheritance mapper is not automatically rendered. Care must be taken in any multiple-table update to explicitly include the joining condition between those tables, even in mappings where this is normally automatic. E.g. if a class Engineer subclasses Employee, an UPDATE of the Engineer local table using criteria against the Employee local table might look like:

this is not accurate for delete(), because multiple table deletes are not supported. I will add this right now.







|

importlogging

fromsqlalchemy importColumn,Float,Integer,String,create_engine

fromsqlalchemy.ext.declarative importdeclarative_base

fromsqlalchemy.orm importSession



Base=declarative_base()



classBird(Base):

    __tablename__ ="bird"

    id=Column(Integer,primary_key=True)

    wing_length =Column(Float)

    bird_type =Column(String)



    __mapper_args__ ={"polymorphic_on":bird_type,

                       "polymorphic_identity":'Bird'

                      }



classPigeon(Bird):

    __mapper_args__ ={"polymorphic_on":Bird.bird_type,

                       "polymorphic_identity":'Pigeon'

                      }



db_path ='C:\\Temp\\testsqllitedb3.db' <smb://Temp//testsqllitedb3.db'>

engine =create_engine('sqlite:///'+db_path,echo=True)

Base.metadata.create_all(engine)


# Turn on logging

logging.basicConfig()

logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)


session =Session(bind=engine)

query =session.query(Pigeon).filter(Pigeon.wing_length >5)


# First query for everything

query.all()


# Then query for deletion

query.delete()

|

When running the all() query, the SQL that is logged to stdout is as
expected -- it includes conditioning both on wing_length, and bird_type

|
2016-09-12 18:26:22,578 INFO sqlalchemy.engine.base.Engine SELECT
bird.id AS bird_id, bird.wing_length AS bird_wing_length, bird.bird_type
AS bird_bird_type
FROM bird
WHERE bird.wing_length > ? AND bird.bird_type IN (?)
2016-09-12 18:26:22,579 INFO sqlalchemy.engine.base.Engine (5, 'Bird')
|


however, the conditioning on bird_type is not present when calling delete():

|
2016-09-12 18:26:22,584 INFO sqlalchemy.engine.base.Engine DELETE FROM
bird WHERE bird.wing_length > ?
2016-09-12 18:26:22,584 INFO sqlalchemy.engine.base.Engine (5,)
|


The documentation includes some caveats about using the bulk delete with
ORM, but from my reading these don't include the behaviour observed
above. Would someone be able to confirm that this is indeed a bug
please? If so, my guess as to the fix is that a few more thinks need to
be added to the QueryContext which is constructed in
orm.persistence.BulkUD._do_pre -- I'm not at all familiar with the code
though, so it's just a hypothesis :)

Thoughts and help would be much appreciated please!

Thanks very much,
Tom


--
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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
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