Thank you Mike for this clear explanation !

Le jeudi 4 mai 2017 16:41:37 UTC+3, Mike Bayer a écrit :
>
>
> > 
> > In my real use case, we have to update both parent and child columns, so 
> > I want to use the Children class. 
>
> so SQLite won't support that (nor will Postgresql or most other DBs). 
> Not possible with standard SQL.   Only MySQL's goofy syntax supports 
> UPDATE where values are modified in multiple tables at once and you need 
> to ensure your query uses filter() to provide the right ON clause. 
>
> note this is *different* from the case where you want to UPDATE values 
> that are only in *one* of the tables, but you still need both tables to 
> find the row.  In that case, Postgresql also supports having multiple 
> tables referred to in an UPDATE.   But still not SQLite.  For SQLite and 
> other databases, the table that's not the target of the update needs to 
> be in a correlated subquery. 
>
> I've updated your test with the final query against the two tables to 
> work on MySQL: 
>
> from sqlalchemy import Column, Integer, String, ForeignKey, create_engine 
> from sqlalchemy.orm import relationship, Session 
> from sqlalchemy.ext.declarative import declarative_base 
>
>
> Base = declarative_base() 
>
>
> class Person(Base): 
>      __tablename__ = 'person' 
>      id = Column(Integer, primary_key=True) 
>      name = Column(String(50)) 
>      type = Column(String(50)) 
>      __mapper_args__ = { 
>          'polymorphic_identity':'person', 
>          'polymorphic_on':type 
>      } 
>
> class Engineer(Person): 
>      __tablename__ = 'engineer' 
>      id = Column(Integer, ForeignKey('person.id'), primary_key=True) 
>      status = Column(String(30)) 
>      __mapper_args__ = { 
>          'polymorphic_identity':'engineer', 
>      } 
>
>
> engine = create_engine("mysql://scott:tiger@localhost/test", echo=True) 
>
> Base.metadata.drop_all(engine) 
> Base.metadata.create_all(engine) 
>
>
> if __name__ == '__main__': 
>      session = Session(engine) 
>      engineer = Engineer(name='me', status='working') 
>
>      # populates 
>      session.add(engineer) 
>      session.commit() 
>
>      session.query(Engineer).filter(Engineer.id == Person.id).\ 
>          filter(Engineer.status == 'working').\ 
>          update({'name': 'bar', 'status': 'done'}) 
>
>
>
> The query at the end comes out as: 
>
> UPDATE engineer, person SET person.name=%s, engineer.status=%s WHERE 
> engineer.id = person.id AND engineer.status = %s 
>
> ('bar', 'done', 'working') 
>
>
> that's totally a MySQL thing.   (also I'd love to see another SQL 
> expression language / ORM anywhere that supports MySQL's multi-table 
> UPDATE :) ) 
>
>

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