On 05/04/2017 09:29 AM, yoch.me...@gmail.com wrote:
Le jeudi 4 mai 2017 16:07:22 UTC+3, Mike Bayer a écrit :
On 05/04/2017 08:41 AM, yoch....@gmail.com <javascript:> wrote:
> Hi,
>
> I'm facing to a strange behavior with bulk update on inherited
class.
>
> Is this a bug ?
it's not.
http://docs.sqlalchemy.org/en/latest/orm/query.html?highlight=query%20update#sqlalchemy.orm.query.Query.update
<http://www.google.com/url?q=http%3A%2F%2Fdocs.sqlalchemy.org%2Fen%2Flatest%2Form%2Fquery.html%3Fhighlight%3Dquery%2520update%23sqlalchemy.orm.query.Query.update&sa=D&sntz=1&usg=AFQjCNFAehd93-iysTyDIJTBu0RctrHV6w>
**Warning**
The Query.update() method is a “bulk” operation, which bypasses ORM
unit-of-work automation in favor of greater performance. **Please read
all caveats and warnings below.**
... below ....
* 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:
session.query(Engineer).\
filter(Engineer.id == Employee.id).\
filter(Employee.name == 'dilbert').\
update({"engineer_type": "programmer"})
Thank you for this response.
In your case, your query is only targeting columns in the base "person"
table. So this is not really a multiple table update and instead of
asking it for query(Engineer) you should be asking for
query(Person).filter(Person.type == 'engineer').
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 :) )
>
> Best regards,
> yoch
>
> --
> 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
<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
<https://groups.google.com/group/sqlalchemy>.
> For more options, visit https://groups.google.com/d/optout
<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
<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.
--
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.