That is what I initially had,

I get the error

sqlalchemy.exc.InvalidRequestError: Select statement 'SELECT type.type
FROM type, thing
WHERE type.id = thing.type_id' returned no FROM clauses due to 
auto-correlation; specify correlate(<tables>) to control correlation 
manually.

On Thursday, February 9, 2017 at 10:02:40 AM UTC-6, Mike Bayer wrote:
>
>
>
> On 02/09/2017 10:14 AM, Shane Carey wrote: 
> > Hi, another question. 
> > 
> > I set my discriminator on the surrogate primary key of its table. 
> > However, when I query for all of a certain discriminator, I get an error 
> > 'Multiple rows returned for subquery'. 
> > 
> > Here is my canonical example 
> > 
> > from sqlalchemy import * 
> > from sqlalchemy import select, and_, event, inspect 
> > from sqlalchemy.orm import * 
> > from sqlalchemy.ext.declarative import * 
> > 
> > Base = declarative_base() 
> > 
> > class Type(Base): 
> > __tablename__ = 'type' 
> > 
> > id = Column(Integer, primary_key=True) 
> > type = Column(String(8), unique=True) 
> > 
> > class Thing(Base): 
> > __tablename__ = 'thing' 
> > 
> > id = Column(Integer, primary_key=True) 
> > type_id = Column(Integer, ForeignKey(Type.id), nullable=False) 
> > 
> > type = relationship(Type) 
> > 
> > __mapper_args__ = { 'polymorphic_on': select([Type.type]).where(Type.id 
> > == type_id).correlate(Type).as_scalar(), 'with_polymorphic': '*' } 
> > 
> > @event.listens_for(Thing, 'init', propagate=True) 
> > def set_identity(instance, *args, **kwargs): 
> > instance.type_id = select([Type.id]).where(Type.type == 
> > object_mapper(instance).polymorphic_identity) 
> > 
> > class Stuff(Thing): 
> > stuff = Column(String(8)) 
> > __mapper_args__ = { 'polymorphic_identity': 'stuff' } 
> > 
> > class Junk(Thing): 
> > junk = Column(String(8)) 
> > __mapper_args__ = { 'polymorphic_identity': 'junk' } 
> > 
> > if __name__ == '__main__': 
> > e = create_engine('mysql+pymysql://user:password@localhost/test', 
> echo=True) 
> > 
> > Base.metadata.drop_all(e) 
> > Base.metadata.create_all(e) 
> > 
> > s = Session(e) 
> > 
> > s.add_all([Type(type='stuff'), Type(type='junk')]) 
> > for i in range(10): 
> > s.add(Stuff(stuff='stuff_{}'.format(i))) 
> > s.add(Junk(junk='junk_{}'.format(i))) 
> > 
> > s.commit() 
> > 
> > res = s.query(Thing).join(Type).filter(Type.type == 'stuff').all() 
> > 
> > #res = s.query(Stuff).all() Also fails 
> > 
> > At first I was receiving the error 'No FROM table specified due to 
> > autocorrelate', but I was able to solve that with 'polymorphic_on': 
> > select([Type.type]).where(Type.id == 
> type_id).correlate(Type).as_scalar() 
> > which I still do not fully understand. The exact error I get is 
>
> I think you want to correlate(Thing) there.  correlate(X) means you 
> don't want "X" in the FROM list in the subquery.    But also the 
> correlation should be automatic here so you wouldn't need to refer to 
> "Thing" in the class def (if you did, you'd need to turn __mapper_args__ 
> into a @declared_attr). 
>
> that is: 
>
> "polymorphic_on": select([Type.type]).where(Type.id == 
> type_id).as_scalar() 
>
> should work 
>
>
>
> > 
> > sqlalchemy.exc.InternalError: (pymysql.err.InternalError) (1242, 
> > 'Subquery returns more than 1 row') [SQL: 'SELECT thing.id AS thing_id, 
> > thing.type_id AS thing_type_id, thing.text AS thing_text, (SELECT 
> > type.type \nFROM type, thing \nWHERE type.id = thing.type_id) AS 
> > _sa_polymorphic_on, thing.stuff AS thing_stuff, thing.junk AS thing_junk 
> > \nFROM thing'] 
> > 
> > it seems like the SQL it should generate is 
> > 
> > SELECT thing.id AS thing_id, 
> > thing.type_id AS thing_type_id, 
> > thing.text AS thing_text, 
> > ( 
> >     SELECT type 
> >     FROM type # this was thing before 
> >     WHERE type.id = thing.type_id 
> > ) AS _sa_polymorphic_on, 
> > thing.stuff AS thing_stuff, 
> > thing.junk AS thing_junk 
> > FROM thing 
> > INNER JOIN type ON type.id = thing.type_id 
> > WHERE type.type = 'junk'; 
> > 
> > but better again would be, this, right? 
> > 
> > SELECT thing.id AS thing_id, 
> > thing.type_id AS thing_type_id, 
> > thing.text AS thing_text, 
> > type.type AS _sa_polymorphic_on, 
> > thing.stuff AS thing_stuff, 
> > thing.junk AS thing_junk 
> > FROM thing 
> > INNER JOIN type ON type.id = thing.type_id 
> > WHERE type.type = 'junk'; 
> > 
> > so I am not sure what is going wrong or how I can generate the correct 
> SQL, 
> > or if possible generate a join rather than a subquery. 
> > 
> > Thanks for you help and patience 
> > 
> > -- 
> > SQLAlchemy - 
> > The Python SQL Toolkit and Object Relational Mapper 
> > 
> > http://www.sqlalchemy.org/ 
> > 
> > To post example code, please provide an MCVE: Minimal, Complete, and 
> > Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> > description. 
> > --- 
> > 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+...@googlegroups.com <javascript:> 
> > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:>>. 
> > To post to this group, send email to sqlal...@googlegroups.com 
> <javascript:> 
> > <mailto:sqlal...@googlegroups.com <javascript:>>. 
> > Visit this group at https://groups.google.com/group/sqlalchemy. 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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