On Sep 29, 7:55 am, "Michael Bayer" <[email protected]> wrote:
> Wyatt Lee Baldwin wrote:
>
> > I have a relation defined like this in a declarative-style class:
>
> >     route = relation(
> >         RouteDef,
> >         primaryjoin=(
> >             (route_number == RouteDef.route_number) &
> >             (route_begin_date >= RouteDef.route_begin_date)
> >         ),
> >     )
>
> > What I *really* want is for `route_number` and `route_begin_date` to
> > be substituted with literal values when I do `instance.route`.
> > Instead, I get a big nasty join that runs forever. Instead of the
> > generated SQL containing a literal date value, for example, the SQL
> > contains the column name, `route_begin_date`.
>
> I don't see this join condition related to the parent (or even what the
> parent is).   So an eagerload will produce a big join, sure.  The join
> expression needs to relate the child to the parent in some way.   Using
> literals within that condition is not an issue.

In my view (which may be warped), a Trip "has one" Route (and many
Trips follow the same Route). Here's more context:

class Trip(Base):
    __tablename__ = 'trip'
    __table_args__ = dict(schema='trans')
    __mapper_args__ = dict(
 
order_by='trip_begin_date,trip_begin_time,route_number,direction')

    route_number = Column(Integer, ForeignKey(RouteDef.route_number),
primary_key=True)
    direction = Column(Integer, primary_key=True)
    service_key = Column(CHAR(3), primary_key=True)
    trip_number = Column(Integer, primary_key=True)
    trip_begin_date = Column(Date, primary_key=True)
    trip_end_date = Column(Date)
    route_begin_date = Column(Date)
    pattern_id = Column(Integer)
    trip_begin_time = Column(Numeric(8))
    trip_end_time = Column(Numeric(8))

    @property
    def route(self):
        """This works, but I want to use a `relation`."""
        try:
            self._route
        except AttributeError:
            session = object_session(self)
            q = session.query(RouteDef)
            q = q.filter(self.route_number == RouteDef.route_number)
            q = q.filter(self.route_begin_date >=
RouteDef.route_begin_date)
            q = q.filter(self.route_begin_date <=
RouteDef.route_end_date)
            self._route = q.one()
        return self._route

Even though `route_number` is defined as a foreign key in the Trip
class, there's not actually a FK constraint in the DB; in practice,
though, `route_number` *is* a FK. `route_begin_date` perhaps should be
a FK, but for legacy reasons, it's not, and that's the reason for the
BETWEEN filtering.

This is how I tried to define the `relation` but which results in a
big join:

    route = relation(RouteDef,
        primaryjoin=(
            (route_number == RouteDef.route_number) &
            (route_begin_date >= RouteDef.route_begin_date) &
            (route_begin_date <= RouteDef.route_end_date)
        )

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to