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].
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