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

Reply via email to