On Oct 12, 2013, at 10:35 PM, Iain Duncan <[email protected]> wrote:


I set up my table  and my mappers like so:

appurl_table = Table("appurls", metadata, 
    Column('tierid', Integer, ForeignKey('tier.tierid'), primary_key=True ),
    Column('groupagentid', Integer, ForeignKey('groupagent.groupagentid'), primary_key=True ),
    autoload=True
)

mappers['AppUrl'] = mapper(AppUrl, appurl_table, properties={
      # specify relationship to Tier
      'tier': relation(Tier, backref='appurls', 
            primaryjoin=(appurl_table.c.tierid == tier_table.c.tierid) ),
      # specify relationship to GroupAgent
      'groupagent': relation(GroupAgent, backref='appurls', 
            primaryjoin=(appurl_table.c.groupagentid == groupagent_table.c.groupagentid) )
    })

And then I attempt a query with a daisy chain of joins and I get the traceback I've posted at the bottom with the message:

ArgumentError: Could not locate any simple equality expressions involving locally mapped foreign key columns for primary join condition 'appurls.groupagentid = groupagent.groupagentid' on relationship AppUrl.groupagent.  Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation. To allow comparison operators other than '==', the relationship can be marked as viewonly=True.

that error isn't from your query, it's from the mappers trying to reconcile the relationships you've set up between them (which is something that happens as soon as you want to use your mappings, like running a query).

My only impression was that maybe that ForeignKey() isn't getting used due to something about the table reflection, but I can't reproduce that.     A quick test is attached, works fine.

Impressions/questions here are:

1. why using mapper() / Table, declarative is much much easier to use ?   provides a lot more configurational advantages. 

1a. also I see usage of the extremely old word "relation", are you working from some very old tutorial or the 0.3 book (e.g. the oreilly book) ?

2. why do you need primaryjoin on gropuagent in the first place, the ForeignKey is all that's needed (I can take it out of my test case, works fine).


from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

e = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
c = e.connect()

t = c.begin()

c.execute("""
create table appurls (
    tierid integer,
    groupagentid integer,
    fooid integer,
    somethingelse integer,
    primary key (groupagentid, tierid, fooid)
)
""")

c.execute("""
create table groupagent (
    groupagentid integer,
    primary key (groupagentid)
)
""")

metadata = MetaData(c)
appurl_table = Table("appurls", metadata,
        Column('tierid', Integer, ForeignKey('tier.tierid'), primary_key=True ),
        Column('groupagentid', Integer, ForeignKey('groupagent.groupagentid'), primary_key=True ),
        autoload=True
)

groupagent_table = Table("groupagent", metadata, autoload=True)

class AppUrl(object):
    pass

class GroupAgent(object):
    pass


mapper(AppUrl, appurl_table, properties={
            'groupagent': relation(GroupAgent, backref='appurls',
                        primaryjoin=(appurl_table.c.groupagentid == groupagent_table.c.groupagentid)
                        )
    })

mapper(GroupAgent, groupagent_table)

s = Session()
print s.query(AppUrl).join(AppUrl.groupagent)








I'm just joining with 
app_url = request.db.query(AppUrl
        ).join(Tier 
        ).join(GroupAgent ( it goes on and on) 

I *thought* I'd specified the join conditions well enough in the above, but clearly I'm missing something, any help much appreciated!
thanks!
Iain

traceback:
  File "/home/qualbe/src/PaymentProxy/paymentproxy/helpers.py", line 30, in get_appurl
    app_url = request.db.query(AppUrl
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/session.py", line 1107, in query
    return self._query_cls(entities, self, **kwargs)
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py", line 115, in __init__
    self._set_entities(entities)
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py", line 124, in _set_entities
    self._set_entity_selectables(self._entities)
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py", line 157, in _set_entity_selectables
    ent.setup_entity(*d[entity])
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/query.py", line 2861, in setup_entity
    self._with_polymorphic = ext_info.with_polymorphic_mappers
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/util/langhelpers.py", line 612, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/mapper.py", line 1458, in _with_polymorphic_mappers
    configure_mappers()
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/mapper.py", line 2153, in configure_mappers
    mapper._post_configure_properties()
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/mapper.py", line 1275, in _post_configure_properties
    prop.init()
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/interfaces.py", line 231, in init
    self.do_init()
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/properties.py", line 1028, in do_init
    self._setup_join_conditions()
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/properties.py", line 1102, in _setup_join_conditions
    can_be_synced_fn=self._columns_are_mapped
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/relationships.py", line 119, in __init__
    self._check_foreign_cols(self.primaryjoin, True)
  File "/home/qualbe/src/eggs/SQLAlchemy-0.8.2-py2.7-linux-x86_64.egg/sqlalchemy/orm/relationships.py", line 626, in _check_foreign_cols
    raise sa_exc.ArgumentError(err)
ArgumentError: Could not locate any simple equality expressions involving locally mapped foreign key columns for primary join condition 'appurls.groupagentid = groupagent.groupagentid' on relationship AppUrl.groupagent.  Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation. To allow comparison operators other than '==', the relationship can be marked as viewonly=True.










--
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to