support UPDATE from query() to subtable ?

Issue #2365 resolved
Mike Bayer repo owner created an issue

We can support query(B).update() where B is a subclass of A if we just assume only "mapper.local_table" is what's being updated.

diff -r 737456866c5f73452249cec0ccae9e9c4c5c545a lib/sqlalchemy/orm/query.py
--- a/lib/sqlalchemy/orm/query.py   Fri Dec 30 15:29:44 2011 -0500
+++ b/lib/sqlalchemy/orm/query.py   Tue Jan 03 10:48:08 2012 -0500
@@ -2593,12 +2593,7 @@
         self = self.enable_eagerloads(False)

         context = self._compile_context()
-        if len(context.statement.froms) != 1 or \
-                    not isinstance(context.statement.froms[0](0), schema.Table):
-            raise sa_exc.ArgumentError(
-                            "Only update via a single table query is "
-                            "currently supported")
-        primary_table = context.statement.froms[0](0)
+        primary_table = self._entity_zero().mapper.local_table

         session = self.session

the trick here becomes if they refer to A in the query. We'd rather not have to add in the WHERE clause for now, so they'd be doing it themselves.

I think if we change the contract of update() and delete() such that:

a. for UPDATE, we use mapper_zero().local_table as the target, and let whatever else is present just go through. Users are responsible for the WHERE clause, we document it. UPDATE..FROM mechanics will kick in here, if available, if they are referring to the parent table also.

b. for DELETE, we use mapper_zero().base_mapper.local_table as the target, and in this case we do ensure that they're using the base class since deleting just the "child" table would create corrupt objects (polymorphic identity points to subtable but subtable row is not present).

Comments (3)

  1. Log in to comment