On Tuesday, November 28, 2017 at 4:10:42 AM UTC+13, Simon King wrote:
>
> On Sun, Nov 26, 2017 at 11:19 AM, Mischa S <mis...@jetbridge.com 
> <javascript:>> wrote: 
> > I want to have a polymorphic table that gets its identity from a column 
> in a 
> > "type" table. I have a "task" table and a "task_type" table. I want to 
> be 
> > able to create task subclasses that say something like: 
> > 
> >     __mapper_args__ = { 
> >         'polymorphic_identity': 'do_stuff_task', 
> >     } 
> > 
> > (Assuming that a row with do_stuff_task is created in the task_type 
> table) 
> > 
> > 
> > Currently in my base Task class I do: 
> > 
> >     task_type_name = 
> > column_property(select([TaskType.task_type]).where(TaskType.id == 
> > task_type_id).as_scalar()) 
> > 
> >     __mapper_args__ = { 
> >         'polymorphic_on': task_type_name, 
> >     } 
> > 
> > 
> > If I try to get say, a user.do_stuff_tasks relationship it emits the 
> > following SQL: 
> > 
> > SELECT 
> >   (SELECT task_type.task_type 
> >    FROM task_type 
> >    WHERE task_type.id = task.task_type_id) 
> > FROM task 
> > WHERE 123 = task.user_id 
> >   AND 
> >     (SELECT task_type.task_type 
> >      FROM task_type 
> >      WHERE task_type.id = task.task_type_id) IN ('do_stuff_task'); 
> > 
> > 
> > This is technically correct, however this query is highly problematic 
> for 
> > us. It does a scan on task in the subquery, which is extremely 
> unpleasant 
> > and basically takes forever. 
> > What I want is something more like: 
> > 
> > SELECT * 
> > FROM task st 
> > JOIN task_type stt ON st.task_type_id=stt.id 
> > WHERE stt.task_type='do_stuff_task' 
> >   AND st.user_id=123; 
> > 
> > Is there some way to rewrite the column_property or polymorphic identity 
> > condition to combine the WHERE conditions in the JOIN instead of doing 
> two 
> > subselects? 
> > 
> > 
> > Thanks! 
>
> Is it strictly necessary for your Task class to be polymorphic? Could 
> you make TaskType polymorphic instead, and then delegate from Task to 
> TaskType? Something like this: 
>
> class Task(Base): 
>     def execute(self): 
>         self.task_type.execute(self) 
>
> class TaskType(Base): 
>     name = sa.Column(sa.String(16)) 
>     __mapper_args__ = { 
>         'polymorphic_on': name, 
>     } 
>     def execute(self, task): 
>         raise NotImplemented 
>
> class DoStuffTaskType(TaskType): 
>     __mapper_args__ = { 
>         'polymorphic_on': 'do_stuff_task', 
>     } 
>     def execute(self, task): 
>         # do stuff 
>
> Simon 
>

We have extra columns per job type on the task table, so I don't think 
that'd work well unless we always referenced the orig task from the task 
type subclasses 

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