has()/any() + joined inh, can't pull needed columns out of aliases when things get crazy

Issue #2195 resolved
Mike Bayer repo owner created an issue

need to adapt this down to be simpler, and also compare to what a non joined inh model would do:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


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

class Location(Base):
   Id = Column( Integer, primary_key =True, autoincrement = True)
   objectType = Column( String(128),nullable = False)
   __tablename__ = 'Location'
   __mapper_args__ = {'polymorphic_on': objectType,'polymorphic_identity': __tablename__}
   name = Column( String(128), nullable =False)

class District(Location):
   Id = Column(Integer,ForeignKey(Location.Id), primary_key = True)
   __tablename__ = 'District'
   __mapper_args__ = {'inherit_condition': Id == Location.Id,'polymorphic_identity': __tablename__}

class Commune(Location):
   Id = Column(Integer,ForeignKey(Location.Id), primary_key = True)
   __tablename__ = 'Commune'
   __mapper_args__ = {'inherit_condition': Id == Location.Id,'polymorphic_identity': __tablename__}
   districtId = Column(Integer,ForeignKey(District.Id))
   district = relation(District, primaryjoin =districtId == District.Id)

class Locality(Location):
   Id = Column(Integer,ForeignKey(Location.Id), primary_key = True)
   __tablename__ = 'Locality'
   __mapper_args__ = {'inherit_condition': Id == Location.Id,'polymorphic_identity': __tablename__}
   communeId = Column(Integer,ForeignKey(Commune.Id))
   commune = relation(Commune, primaryjoin = communeId== Commune.Id)

Base.metadata.create_all(engine)

# I want all localities which are in a district called Foo

s = Session(engine)

#q = s.query(Locality).filter(Locality.commune.has(name='Foo'))

q = s.query(Locality).filter(
    Locality.commune.has(
#        (Locality.name =='foo') 
        Commune.district.has(District.name=='foo')
    )
)

q.all()

#print s.query(Locality).filter(Locality.coohas(
#    Commune.district.has(Commune.name=="foo")
#))

Comments (5)

  1. Mike Bayer reporter

    fix is attached. Need to test:

    1. the fix to the "clone" call in Alias. This was ultimately not needed here though.
    2. the new "_no_adapt" flag added to adaptation. Maybe call it "_no_replacement" or "stop_on_replacement".
    3. figure out if there's any possible negative effect of blocking the "polymorphic" selectable from being traversed. there shouldn't be.
    4. can we use this approach in more places to simplify things ?
  2. Log in to comment