On Aug 23, 2013, at 6:07 PM, Kyle Marek-Spartz <[email protected]> wrote:
> Hello,
>
> I've ran into a potential issue with OrderingList. When we are creating a new
> child, we'd like to be able to simply specify child.parent (or
> child.parent_id), and have child.position be updated appropriately when
> committed. This saves querying for the parent object, and then appending the
> child to the list.
well in the first case, say we have this:
s = Session.query(Slide).get(1)
b = Bullet()
b.slide = s
when we load Slide, slide.bullets is unloaded. The orderinglist can't do its
job here without emitting a SELECT for slide.bullets first. As it turns out,
this doesn't occur in this case. Setting b.slide = someslide was optimized a
long time ago to not emit a usually wasteful SELECT of the other side of the
collection.
If you were to say this:
s = Session.query(Slide).get(1)
s.bullets
b = Bullet()
b.slide = s
then it sets "position", because "b.slide = s" emits the backref to
"s.bullets.append" and you get the ordering behavior.
So when you say, "this saves querying for the parent object", if you're looking
for saving on the performance of a SELECT, you're not going to get that. If
you're looking for that it should "just work" without any explicit code, then
yes we need some extra help here. I'm not sure what we should do to
orderinglist directly, this should at least be documented, but here is how you
can make sure s.bullets is present:
from sqlalchemy import event
@event.listens_for(Bullet.slide, "set")
def ping_slide_bullets(target, value, oldvalue, initiator):
value.bullets
return value
of course in your example, you need to keep that Slide object attached to the
Session (don't keep closing the session and creating new ones) otherwise it
can't emit the lazyload for "bullets".
For the second part of the example, that's a totally different thing, that's
the "I want to set bar.foo_id = 7 and have it act like bar.foo =
Session.query(Foo).get(7)" There's an FAQ entry which also refers to a wiki
recipe that, using more events, can approximate this behavior for the typical
case:
http://docs.sqlalchemy.org/en/rel_0_8/faq.html#i-set-the-foo-id-attribute-on-my-instance-to-7-but-the-foo-attribute-is-still-none-shouldn-t-it-have-loaded-foo-with-id-7
.
signature.asc
Description: Message signed with OpenPGP using GPGMail
