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.

Reply via email to