A given A.id can only be in any one of field1id or field2id in an
instance of B but a B is made up of different A's and hence field1id
and field2id will be different A.id's which cannot appear in any other
object of B.
I'll try to illustrate the actual problem I had.
We have 2 classes Person and Address.
A person can have multiple addresses
Person.py
class Person(declarative_base):
_primaryAddressId = Col()
_primaryAddress = relationship(Address.Address, uselist=False,
primaryjoin= lambda:Address.Address.id==Person.primaryAddressId),
back_populate="_person")
_secondaryAddressId = Col()
_secondaryAddress = relationship(Address.Address, uselist=False,
primaryjoin= lambda:Address.Address.id==Person.secondaryAddressId),
back_populate="_person")
Address.py
class Address(declarative_base):
_person=relationship("Person",
primaryjoin="or_(Address._id==Person._primaryAddressId,
Address.id==Person._secondaryAddressId)",uselist=False)
In this case the following conditions apply -
* A person has a primary and secondary address which no other person
may have.
* A primary address != a secondary address
* Only 1 person may live at any address. (There are no families in
this realm)
If in the future I am to add a vacationAddress field or remove any
previously present I will need to edit the primaryjoin in Address
which is a drone. I am looking for a smarter way to accomplish this.
Best,
Aman
On Feb 2, 4:36 pm, Michael Bayer <[email protected]> wrote:
> why have "B.field1d" and separate "B.field2id" then if a given A.id can only
> be in one and only one field1id/field2id ? If you had only one column you
> could at least apply a UNIQUE constraint to it and enforce the 1:1.
>
> On Feb 2, 2012, at 4:31 PM, Manpreet Bhurji wrote:
>
>
>
>
>
>
>
> > Thanks Michael. Really appreciate the quick reply.
>
> > A syntax error in the primary was the reason that back_populate did
> > not work. Fixing that solved it.
>
> > I should have mentioned that field1 and field2 can only have a 1:1
> > relationship towards A. I mean if field1 is assigned to an instance of
> > A, it can't be assigned to any other. So any instance of A will have
> > relationship "b" which only points to 1 B instance.
>
> > The primary join in the A (when I am using back_populate) is now a
> > long string which will need to be edited if I ever change the model B.
> > Any ideas on how I might make this better?
>
> > Regards,
> > Aman
>
> > On Feb 2, 3:36 pm, Michael Bayer <[email protected]> wrote:
> >> On Feb 2, 2012, at 3:16 PM, Manpreet Bhurji wrote:
>
> >>> I have a structure like this
> >>> A.py
> >>> class A:
> >>> _some_fields
>
> >>> B.py
> >>> class B:
> >>> _field1id = Column(...)
> >>> _field1 = relationship( A.A, primaryjoin=lambda:A.A.id==B.field1id,
> >>> backref="b", uselist=False )
> >>> _field2id = Column(...)
> >>> _field2 = relationship( A.A, primaryjoin=lambda:A.A.id==B.field2id,
> >>> backref="b", uselist=False )
>
> >>> I know this will not work because the relationship field1 has already
> >>> created "b" on A.
> >>> I have tried using back_populates="b" in place of backref in class B
> >>> and adding
> >>> _b = relationship( "B", primaryjoin="or_(A.id==B.field1id,
> >>> A.id==B.field2id)" ) to A
>
> >>> Any ideas on how I would go about this?
>
> >> What object would A.b return if its "id" were present both in the
> >> "field1id" of one particular "B", and in the "field2id" of another ?
> >> Would A.b be a collection of both ? If so this requires a union of some
> >> kind, most easily done in Python. Naming the backrefs "b_from_field1"
> >> and "b_from_field2", we'd say:
>
> >> class A(Base):
> >> @property
> >> def b(self):
> >> return self.b_from_field1.union(self.b_from_field2)
>
> >> it's also possible to create a relationship A.b that selects from both
> >> field1id and field2id by creating a UNION and then mapping B to that union
> >> using non_primary=True, then using that mapper as the target of A.b,
> >> though this is a little more involved.
>
> >> In both cases A.b is read-only since it cant be determined if new B()
> >> entries would be established via the B._field1 relationship or the
> >> B._field2 relationship.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "sqlalchemy" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> > [email protected].
> > For more options, visit this group
> > athttp://groups.google.com/group/sqlalchemy?hl=en.
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.