On 27.8.2015 22:13, Douglas Russell wrote:
> 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.

+100

I came to the same conclusion a long time ago and have never looked back :-)

Just my 2c,

Ladislav Lenart


> 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
>>     
>> <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
> <mailto:sqlalchemy+unsubscr...@googlegroups.com>.
> To post to this group, send email to sqlalchemy@googlegroups.com
> <mailto:sqlalchemy@googlegroups.com>.
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.


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