On Sun, Nov 26, 2017 at 11:19 AM, Mischa S <[email protected]> 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
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.