On Thu, Sep 6, 2018 at 4:21 AM, Tomáš Sandrini <warecz...@gmail.com> wrote: > Hi, > > I am writing a library where I need to hide (for normal usage, since that > will be 90% use case) the existence of a Parent object, > basically limiting it just to one property and then set the Parent manually > within the Child class through this one property. > An obvious solution to this would be to get the session within the > constructor and set it from here, but that breaks the ORM philosophy > and I would like to find something more cleaner. > So I found the 'init_scalar' ORM event, which is perfectly suited for this > issue, but unfortunately it doesn't fire at all for me.
the init_scalar event is a strange little event to suit one of the less appealing things SQLAlchemy has to do, which is to give you an answer when you access an attribute on an object that has no value. By "access", we mean reading it, not anything else. E.g.: print(Children.parent_id) The answer SQLAlchemy gives you in modern versions is "None", and nothing happens to the state of the object. In older versions, it used to actually set the attribute's state to None, that is, reading the attribute had a side effect. When I fixed the attribute system to not need that anymore, the events were added in case someone wanted to customize this, in that i can restore the old behavior. I doubt anyone uses this event for anything, though. I'm not even sure why I wrote all those docs for it (and even an example...) because it seems kind of strange you'd want to persist a special value only if someone "read" from it, I guess I was nervous about people upgrading from the old behavior. So I think this is a case of docs being misleading. In this case, if the thing you need to do your thing is a Session, you can catch exactly when that is available using the transient_to_pending lifecycle event: http://docs.sqlalchemy.org/en/latest/orm/session_events.html?highlight=session%20lifecycle#transient-to-pending this works @event.listens_for(Session, "transient_to_pending") def init_parent(session, instance): if isinstance(instance, Child): # or whatever mixin, or call a method on the class, etc. with sess.no_autoflush: parent = sess.query(Parent).filter(Parent.name == instance.name).one() instance.parent = parent > > This snippet describes what I am trying to accomplish -> > https://pastebin.com/GEccd7zu > > I will appreciate any kind of help. > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > description. > --- > 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 https://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- 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 https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.