Thanks, I ran a similar script without any problems. It seems there's a 
modification somewhere to the Base we are using that causes the conflict.

On Thursday, June 12, 2014 12:26:45 PM UTC-4, Simon King wrote:
>
> For what it's worth, the following script works for me, but I only 
> have access to sqlite at the moment, which doesn't support multiple 
> schemas, so I had to comment those bits out. If you uncomment those 
> and run it against your database, does it fail? If so, the problem 
> would seem to be something to do with the tables being in different 
> schemas. 
>
> from sqlalchemy import (Column, ForeignKey, Enum, Integer, 
>                         String, Text, CheckConstraint, Numeric, 
>                         create_engine) 
> from sqlalchemy.orm import relationship, sessionmaker, backref 
> from sqlalchemy.ext.declarative import declarative_base 
>
> Base = declarative_base() 
>
> class ServiceInstance(Base): 
>     __tablename__ = 'services' 
>     #__table_args__ = ( 
>     #    {'schema': 'customer_inquiry'} 
>     #    ) 
>
>     service_id = Column(Integer, primary_key=True) 
>     service_instance_id = Column(String(12), unique=True) 
>     title = Column(String(255)) 
>     definition_title = Column(String(255), nullable=False) 
>     description = Column(Text) 
>     #category = Column(ForeignKey(ServiceCategory.category), 
> nullable=False) 
>     price = Column(Numeric, CheckConstraint('price >= 0'), nullable=False) 
>     units_included = Column( 
>         Numeric, 
>         CheckConstraint('units_included IS NULL OR units_included >= 0')) 
>     unit_price = Column( 
>         Numeric, 
>         CheckConstraint('unit_price IS NULL OR unit_price >= 0')) 
>
> class Endpoint(Base): 
>     __tablename__ = 'endpoints' 
>     #__table_args__ = {'schema': 'nms'} 
>
>     service_id = Column(ForeignKey(ServiceInstance.service_id), 
>                         primary_key=True) 
>     endpoint_type = Column(Enum('Service', 'Address')) 
>     service_instance = relationship( 
>         ServiceInstance, 
>         foreign_keys=service_id, 
>         backref=backref('endpoints', cascade='all, delete-orphan')) 
>
> if __name__ == '__main__': 
>     engine = create_engine('sqlite://', echo='debug') 
>     Session = sessionmaker(bind=engine) 
>
>     Base.metadata.create_all(bind=engine) 
>
>
> On Thu, Jun 12, 2014 at 5:19 PM, Simon King <[email protected] 
> <javascript:>> wrote: 
> > In that case, could you send a stripped-down single-file test case 
> > with just those 2 classes that shows the problem? 
> > 
> > Thanks, 
> > 
> > Simon 
> > 
> > On Thu, Jun 12, 2014 at 5:13 PM,  <[email protected] <javascript:>> 
> wrote: 
> >> I have tried calling relationship without foreign_keys or primaryjoin, 
> in 
> >> which case I get an error message suggesting I specify foreign_keys. 
> Base is 
> >> the same class for both model classes in the case where this does not 
> work. 
> >> When each model class has a different Base class things work fine. Also 
> it 
> >> is a 1-to-1 relationship, I just missed that s in the backref. 
> >> 
> >> On Thursday, June 12, 2014 12:03:29 PM UTC-4, Simon King wrote: 
> >>> 
> >>> On Thu, Jun 12, 2014 at 4:39 PM,  <[email protected]> wrote: 
> >>> > I can't seem to construct a relationship against this 
> ServiceInstance 
> >>> > class 
> >>> > without having 
> >>> > the Endpoint class inherit from a new declarative_base(). I've tried 
> >>> > several 
> >>> > different 
> >>> > methods of calling relationship() and the error messages are fairly 
> >>> > similar. 
> >>> > Below I've 
> >>> > shown the two classes as well as the various relationship() calls 
> and 
> >>> > the 
> >>> > resulting 
> >>> > errors. I'm new to SQLAlchemy so apologies if I'm overlooking 
> something 
> >>> > very 
> >>> > basic, but I 
> >>> > don't understand the errors given that I have service_id = Column( 
> >>> > ForeignKey(ServiceInstance.service_id), primary_key=True) 
> >>> > 
> >>> > class Endpoint(Base): 
> >>> >     __tablename__ = 'endpoints' 
> >>> >     __table_args__ = {'schema': 'nms'} 
> >>> > 
> >>> >     service_id = Column(ForeignKey(ServiceInstance.service_id), 
> >>> >                         primary_key=True) 
> >>> >     endpoint_type = Column(Enum('Service', 'Address')) 
> >>> >     service_instance = relationship( 
> >>> >             ServiceInstance, 
> >>> >             foreign_keys=service_id, 
> >>> >             backref=backref('endpoints', cascade='all, 
> delete-orphan')) 
> >>> > 
> >>> > 
> >>> > class ServiceInstance(Base): 
> >>> >     __tablename__ = 'services' 
> >>> >     __table_args__ = ( 
> >>> >         {'schema': 'customer_inquiry'} 
> >>> >     ) 
> >>> > 
> >>> >     service_id = Column(Integer, primary_key=True) 
> >>> >     service_instance_id = Column(String(12), unique=True) 
> >>> >     title = Column(String(255)) 
> >>> >     definition_title = Column(String(255), nullable=False) 
> >>> >     description = Column(Text) 
> >>> >     category = Column(ForeignKey(ServiceCategory.category), 
> >>> > nullable=False) 
> >>> >     price = Column(Numeric, CheckConstraint('price >= 0'), 
> >>> > nullable=False) 
> >>> >     units_included = Column( 
> >>> >             Numeric, 
> >>> >             CheckConstraint('units_included IS NULL OR 
> units_included >= 
> >>> > 0')) 
> >>> >     unit_price = Column( 
> >>> >             Numeric, 
> >>> >             CheckConstraint('unit_price IS NULL OR unit_price >= 
> 0')) 
> >>> > 
> >>> > sqlalchemy.exc.NoForeignKeysError: Could not determine join 
> condition 
> >>> > between parent/child 
> >>> > tables on relationship Endpoint.service_instance - there are no 
> foreign 
> >>> > keys 
> >>> > linking these 
> >>> > tables.  Ensure that referencing columns are associated with a 
> >>> > ForeignKey or 
> >>> > ForeignKeyConstraint, or specify a 'primaryjoin' expression. 
> >>> > 
> >>> > 
> >>> >     service_instance = relationship( 
> >>> >             ServiceInstance, 
> >>> >             primaryjoin=service_id == ServiceInstance.service_id, 
> >>> >             backref=backref('endpoints', cascade='all, 
> delete-orphan')) 
> >>> > 
> >>> > sqlalchemy.exc.ArgumentError: Could not locate any simple equality 
> >>> > expressions involving 
> >>> > locally mapped foreign key columns for primary join condition 
> >>> > 'nms.endpoints.service_id = 
> >>> > customer_inquiry.services.service_id' on relationship 
> >>> > Endpoint.service_instance. 
> >>> > 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. 
> >>> > 
> >>> > 
> >>> >     service_instance = relationship( 
> >>> >             ServiceInstance, 
> >>> >             primaryjoin=service_id == ServiceInstance.service_id, 
> >>> >             viewonly=True, 
> >>> >             backref=backref('endpoints', cascade='all, 
> delete-orphan')) 
> >>> > 
> >>> > sqlalchemy.exc.ArgumentError: Can't determine relationship direction 
> for 
> >>> > relationship 
> >>> > 'Endpoint.service_instance' - foreign key columns are present in 
> neither 
> >>> > the 
> >>> > parent nor 
> >>> > the child's mapped tables 
> >>> > 
> >>> 
> >>> With those column definitions, this should Just Work - you shouldn't 
> >>> need foreign_keys or primaryjoin parameters in the relationship 
> >>> definition, since there is only 1 foreign key and no ambiguity. 
> >>> 
> >>> (I'm slightly confused by your columns though - is service_id really 
> >>> the only primary key of Endpoint? In which case, this would have to be 
> >>> a 1-to-1 relationship, but your "endpoints" backref implies that you 
> >>> expect there to be more than one endpoint per service) 
> >>> 
> >>> Did you say that "Base" is the same class in both cases? Foreign key 
> >>> relationships are looked up in the Metadata instance which is attached 
> >>> to the declarative_base class, so if you have 2 different Base 
> >>> classes, SA won't be able to resolve the foreign keys. You can work 
> >>> around this by getting the 2 Base classes to share the same Metadata 
> >>> instance: 
> >>> 
> >>> 
> >>> 
> http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative.html#accessing-the-metadata
>  
> >>> 
> >>> Hope that helps, 
> >>> 
> >>> Simon 
> >> 
> >> -- 
> >> 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] <javascript:>. 
> >> To post to this group, send email to [email protected] 
> <javascript:>. 
> >> Visit this group at http://groups.google.com/group/sqlalchemy. 
> >> For more options, visit https://groups.google.com/d/optout. 
>

-- 
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/d/optout.

Reply via email to