Ok, thanks, that makes sense. Generally everything I see about SQLAlchemy referencing is using backref and it is convenient, but knowing that you actually think back_populates would be your preferred way to implement things is quite nice. I quite prefer that as I think it makes my code much more readable to have the relationship properties declared where they will exist.
Cheers, Douglas On Monday, 24 August 2015 21:54:17 UTC-4, Michael Bayer wrote: > > > > On 8/24/15 9:21 PM, Mike Bayer wrote: > > > > On 8/24/15 7:41 PM, Douglas Russell wrote: > > > def print_stuff(mapper, class_): > print getattr(class_, 'books') > > event.listen(mapper, 'mapper_configured', print_stuff) > > author = Author(name='Chuck Paluhniuk') > > When I run this code, the result is that when Author is first used, the > 'mapper_configured' event will fire and my print_stuff function callback > will run. > > The results is this: > > Traceback (most recent call last): > File "marshmallow_experiment.py", line 37, in <module> > author = Author(name='Chuck Paluhniuk') > File "<string>", line 2, in __init__ > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", > > line 347, in _new_state_if_none > state = self._state_constructor(instance, self) > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", > > line 747, in __get__ > obj.__dict__[self.__name__] = result = self.fget(obj) > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", > > line 177, in _state_constructor > self.dispatch.first_init(self, self.class_) > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/event/attr.py", > > line 258, in __call__ > fn(*args, **kw) > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", > > line 2792, in _event_on_first_init > configure_mappers() > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", > > line 2691, in configure_mappers > mapper, mapper.class_) > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/event/attr.py", > > line 218, in __call__ > fn(*args, **kw) > File > "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sqlalchemy/orm/events.py", > > line 527, in wrap > fn(*arg, **kw) > File "marshmallow_experiment.py", line 33, in print_stuff > print getattr(class_, 'books') > AttributeError: type object 'Author' has no attribute 'books' > > Should not the backref be configured at that point? What I'm trying to do > is use the mapper_configured event in order to autocreate > marshamallow-sqlalchemy schemas, which works fine except that because books > doesn't exist at the point when the callback function runs, the resulting > schema is also missing the books part. > > If I do this instead: > > author = Author(name='Chuck Paluhniuk') > print_stuff(None, Author) > > Then the result is: > > Author.books > > so you can see what's happening here. Author.books is being set up, but > not within the event. In this case Author is being configured before Book, > and as far as it knows, that's it, it's done. The event is called. Book > hasn't been touched so therefore neither has "books". Only outside of the > whole thing, where Book also got set up, does your inspection work. > > The solution is to either use back_populates instead of backref, which is > probably the only way the ORM would have done it today if starting again, > or use the "after_configured()" event > <http://docs.sqlalchemy.org/en/rel_1_0/orm/events.html#sqlalchemy.orm.events.MapperEvents.after_configured> > http://docs.sqlalchemy.org/en/rel_1_0/orm/events.html#sqlalchemy.orm.events.MapperEvents.after_configured > > which is intentionally here so that you can do things that require all > known mappers to be fully set up, which is the case here. > > As is so often the case I'm horrified the API docs don't have cross > linking here. doing that.. > > I've pushed up new descriptions and full cross-linking between > configure_mappers(), mapper_configured(), before_configured() and > after_configured(), for 0.9, 1.0, 1.1, master. Should be up on the site in > a little while. > -- 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.