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,  <ty...@beanfield.com> 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,  <ty...@beanfield.com> 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 sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> 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 sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to