On Tue, Jul 1, 2014 at 2:17 PM, Mike Bayer <mike...@zzzcomputing.com> wrote:

>
> On 7/1/14, 4:54 PM, Ken Lareau wrote:
>
>  Related to one of my recent posted threads here, I'm recalling a certain
> conversation at PyCon where I was mentioning how a friend would define
> a many-to-many relationship by defining a relationship on both declarative
> classes involved, each pointing to the other, and the look of abject horror
>  I received gave a good indication that this is very often not a good
> thing.
>  However, I've run into a situation where this has proven useful:
>
> class Deployment(Base):
>     __tablename__ = 'deployments'
>
>     id = Column(u'DeploymentID', INTEGER(), primary_key=True)
>     package_id = Column(
>         INTEGER(),
>         ForeignKey('packages.package_id', ondelete='cascade'),
>         nullable=False
>     )
>
>     package = relationship('Package')
>
>
> class Package(Base):
>     __tablename__ = 'packages'
>
>     id = Column(u'package_id', INTEGER(), primary_key=True)
>     pkg_name = Column(String(length=255), nullable=False)
>     version = Column(String(length=63), nullable=False)
>     revision = Column(String(length=63), nullable=False)
>
>     deployments = relationship('Deployment')
>
>  In this case, most of the time I'm looking to determine which deployments
>  a given package belongs to, but there are times when I have a given
>  deployment and am curious as to what package(s) are related to it, and
>  unless I'm misunderstanding something (which I won't rule out I could
> be), a backref won't easily help in this instance.
>
> I'm not actually familiar with what you mean by "a backref won't easily
> help".   Above, Package.deployments and Deployment.package refer to the
> same linkage between the two classes, just in different directions.   A
> backref above is equivalent to what you have, plus:
>
> class Deployment(Base):
>    # ...
>
>   package = relationship("Package", back_populates='deployments')
>
> class Package(Base):
>   # ...
>
>   deployments = relationship("Deployment", back_populates='package')
>
> the importance of back_populates (or backref, essentially a shortcut to
> the same thing) is mostly in how the collection or attribute responds to
> in-Python changes and to a lesser (but sometimes important) extent how the
> attributes are treated during the flush process.   The two relationships
> don't have to be related to each other at the Python level like this, but
> there's usually no reason to omit this information as it only allows the
> ORM to better keep the two sides in sync.
>

Oy, leave it to me to misinterpret once again (and I have read that part
of the docs before, so I should have known better).  For some reason
I had in my head that the backref could only be used from the class that
the relationship was defined on. :-/


>
>
>
>  Of course, one of the gotchas in using this (and we did hit it in one of
> our queries) is if not careful, one can trigger a nice 'maximum recursion
>  depth exceeded' exception (in our particular case, a 'joinedload' within
>  the query was able to resolve that issue) and I'm sure there other poten-
> tial "gotchas", so I guess this leads back to the main question at hand:
>
> I don't doubt that this can happen but I'm not familiar at the moment what
> the nature of this recursion issue would be.
>

Talking with my coworker again, I believe I may have misspoke on the
'joinedload' solving the issue (we used that for performance improvements
I think), but it was while we were trying things out that we caused the
recursion issue and sadly neither of us can remember exactly what trig-
gered that!   So please forget that part, my memory is terrible as of late.
*smile*


>   Are there times when using "reciprocal" relationships is okay, and are
> there certain things that should be done to mitigate potential issues that
>  can be caused by doing so, or are there better ways to accomplish the
> same thing?
>
>
> It's not clear to me what the "thing" is that you want to accomplish
> here.  If it's just, you want to set up the two relationships as explicit
> code for readability, that's great, use back_populates.   This is probably
> how apps should be doing it anyway, in the early SQLAlchemy days there was
> a lot of pressure to not require too much boilerplate, hence "backref".
> These days, the community has moved well past the whole notion of "super
> minimal declaration / magic == good", thankfully.
>

We've gone ahead and utilized the 'back_populates' for this case, and
I thank you for the assistance and clarification here!

-- 
- Ken Lareau

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