Thanks for the quick response. I added query.join_to('street_name') to
the query.select and that seems to be working (and is much nicer than
the get-street_name_ids-first method).

One thing I don't understand is why I don't need a query.join_to for
the nodes, cities, and states tables too, since they are related to
the streets table similarly to the way street_names is. The only
difference I see is that I specified primaryjoin for the other tables
but not for street_names, but when I tried adding primaryjoin for
street_names, it didn't (seem to) do anything.

I don't really need an answer to that question, mostly just curious.

Thanks again,

--
Wyatt Baldwin
byCycle.org


On 9/18/06, Michael Bayer <[EMAIL PROTECTED]> wrote:
> OK, youre doing pretty good.  theres one behavior of Query which is
> less than convenient for a case like this, which is that when you use
> multiple tables in the <whereclause> of a session.query
> (SomeClass).select(<whereclause>) , namely tables that are outside
> the scope of the primary table of the mapper which you are querying,
> it will not make any assumptions whatsoever about the join conditions
> to those other tables, *even* if those other tables are part of
> relationships to that mapper.
>
> so you can either explicitly specify all the join conditions in your
> call to select(), or you can get some help in generating them by
> using any of the following tools:
>
>         query.select_by()
>         query.join_by()
>         query.join_via()
>
> which *do* make usage of the relations off the mapper, and which are
> described at:  http://www.sqlalchemy.org/docs/
> datamapping.myt#datamapping_selectrelations_jointo
>
>
>
> On Sep 18, 2006, at 9:03 PM, Wyatt Baldwin wrote:
>
> > Preface: I'm converting an app from MySQL/MySQLdb to
> > PostgreSQL/psycopg2/SQLAlchemy. My general SQL experience is limited,
> > and this is my first time using SQLAlchemy. So far, the conversion
> > process has been mostly smooth and I've been able to clean up a lot of
> > things.
> >
> >
> > I've just started getting into the ORM aspects of SQLAlchemy and I'm
> > trying to do something fairly complicated (I guess):
> >
> > - The user enters a free-form street address, which may be only partly
> > specified (that is, certain parts, like city or zip code might be
> > missing).
> >
> > - The app looks for all streets (AKA edges) in the database that match
> > what the user entered and returns a list of street objects. Here's the
> > query I'm trying to use to accomplish this:
> >
> >         edges = query.select(and_(
> >             func.least(streets.c.addr_f, streets.c.addr_t) <= num,
> >             num <= func.greatest(streets.c.addr_f, streets.c.addr_t),
> >             street_names.c.prefix == street_name.prefix,
> >             street_names.c.name == street_name.name,
> >             street_names.c.sttype == street_name.sttype,
> >             street_names.c.suffix == street_name.suffix
> >             cities.c.city == place.city,
> >             states.c.id == place.state_id,
> >             or_(c.zip_code_l == place.zip_code, c.zip_code_r ==
> > place.zip_code),
> >         ))
> >
> > The problem is, in cases where there should be only one result, there
> > are, for example, 38. The part that seems to be borked is the
> > street_names stuff (something to do with the way the tables are
> > joined???).
> >
> > The streets table has a foreign key pointer, street_name_id, to the
> > street names table (see table defs below). If I get the
> > street_name_ids in a separate query and do the following, I get the
> > expected number of results:
> >
> >         edges = query.select(and_(
> >             func.least(streets.c.addr_f, streets.c.addr_t) <= num,
> >             num <= func.greatest(streets.c.addr_f, streets.c.addr_t),
> >             streets.c.street_name_id.in_(*street_name_ids),
> >             cities.c.city == place.city,
> >             states.c.id == place.state_id,
> >             or_(c.zip_code_l == place.zip_code, c.zip_code_r ==
> > place.zip_code),
> >         ))
> >
> >
> > Here's how things are set up (with some stuff left out for clarity):
> >
> > Tables
> > ===================
> >
> > streets = Table(
> >             'layer_streets',
> >             metadata,
> >             Column('id', Integer, primary_key=True),
> >             Column('geom', Geometry, nullable=False),
> >
> >             Column('node_f_id', Integer,
> >                    ForeignKey('layer_nodes.id'),
> >                    nullable=False),
> >             Column('node_t_id', Integer,
> >                    ForeignKey('layer_nodes.id'),
> >                    nullable=False),
> >
> >             Column('addr_f', Integer),
> >             Column('addr_t', Integer),
> >
> >             Column('even_side', CHAR(1)),
> >
> >             Column('street_name_id', Integer, ForeignKey
> > ('street_names.id'),),
> >
> >             Column('city_l_id', Integer, ForeignKey('cities.id')),
> >             Column('city_r_id', Integer, ForeignKey('cities.id')),
> >
> >             Column('state_l_id', CHAR(2), ForeignKey('states.id'),
> >                    nullable=False),
> >             Column('state_r_id', CHAR(2), ForeignKey('states.id'),
> >                    nullable=False),
> >
> >             Column('zip_code_l', Integer),
> >             Column('zip_code_r', Integer),
> >
> >             schema=schema,
> >             ),
> >
> > street_names =  Table(
> >             'street_names',
> >             metadata,
> >             Column('id', Integer, primary_key=True),
> >             Column('prefix', String(2)),
> >             Column('name', String, nullable=False),
> >             Column('sttype', String(4)),
> >             Column('suffix', String(2)),
> >             schema=schema,
> >             ),
> >
> >
> > Objects
> > ===================
> >
> > class Street:
> >     """Things and stuff which is not relevant to this discussion."""
> >
> > class StreetName:
> >     """Things and stuff which is not relevant to this discussion."""
> >
> >
> > Mappers
> > ===================
> >
> > street_name_mapper = orm.mapper(
> >     StreetName,
> >     street_names,
> > )
> >
> > edge_mapper = orm.mapper(
> >     Street,
> >     layer_streets,
> >     properties={
> >         'node_f': orm.relation(
> >             Node,
> >             primaryjoin=layer_streets.c.node_f_id ==
> >             layer_nodes.c.id,
> >             ),
> >         'node_t': orm.relation(
> >             Node,
> >             primaryjoin=layer_streets.c.node_t_id ==
> >             layer_nodes.c.id,
> >             ),
> >         'street_name': orm.relation(
> >             StreetName,
> >             ),
> >         'city_l': orm.relation(
> >             City,
> >             primaryjoin=layer_streets.c.city_l_id ==
> >             cities.c.id,
> >             ),
> >         'city_r': orm.relation(
> >             City,
> >             primaryjoin=layer_streets.c.city_r_id ==
> >             cities.c.id,
> >             ),
> >         'state_l': orm.relation(
> >             State,
> >             primaryjoin=layer_streets.c.state_l_id ==
> >             states.c.id,
> >             ),
> >         'state_r': orm.relation(
> >             State,
> >             primaryjoin=layer_streets.c.state_r_id ==
> >             states.c.id,
> >             ),
> >     }
> > )
> >
> >
> > So, the question is, then, of course, what am I doing wrong? Is it the
> > query? The mapper? Should I define another mapper for this purpose?
> > Would this be a lot easier if I just knew more about SQL in general?
> >
> > Any tips, pointers, or hints will be most appreciated.
> >
> > --
> > Wyatt Baldwin
> > byCycle.org
> >
> > ----------------------------------------------------------------------
> > ---
> > Take Surveys. Earn Cash. Influence the Future of IT
> > Join SourceForge.net's Techsay panel and you'll get the chance to
> > share your
> > opinions on IT & business topics through brief surveys -- and earn
> > cash
> > http://www.techsay.com/default.php?
> > page=join.php&p=sourceforge&CID=DEVDEV
> > _______________________________________________
> > Sqlalchemy-users mailing list
> > Sqlalchemy-users@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users
>
>


-- 
Wyatt Baldwin
byCycle.org

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users

Reply via email to