The core of the issue is that this:

ub.book = book

places UserBook into the Session via cascades.  Usually this is convenient.   
However, it can be tailored to behave more accurately.

WIthout any changes, for this use case I usually just construct association 
objects with all their state at once:

UserBook(book=mybook, user=myuser)

Another method is to attach "book" after user.reads has been accessed:

user.reads.append(ub)
ub.book = book

In some cases, when I have a lot going on that i need autoflush to not get in 
the way, I'll turn it off temporarily:

session.autoflush = False
<do stuff>
session.autoflush = True

some recipes for that are at 
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush

Then finally, you can make "ub.book = book" not actually place UserBook in the 
session by setting cascade_backrefs=False, docs for that at 
http://www.sqlalchemy.org/docs/orm/session.html#controlling-cascade-on-backrefs 


On Dec 18, 2011, at 7:05 AM, Manav Goel wrote:

> Thanks for the answer.
> Yes this comes in trace
> File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/
> site-packages/sqlalchemy/orm/query.py", line 2031, in __iter__
>    self.session._autoflush()
> 
> What is the workaround this?
> 
> On Dec 17, 10:32 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
>> On Dec 17, 2011, at 6:26 AM,ManavGoelwrote:
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>>> Hi
>>>       I created a many to many relation between two tables as shown
>>> in the tutorial using Association object as I have extra fields in
>>> connecting table.
>>> I have table User(user_id), Book(book_id) and UserBook(user_id,
>>> book_id)
>> 
>>> This code gave me Integrity error of UserBook.user_id of being null.
>>> Basically it is not user id of user automatically to UserBook object :
>> 
>>> def con(user, mybook):
>>>     ub = UserBook()
>>>     ub.book = mybook
>>>     user.reads.append(ub)
>>>     session.commit()
>> 
>>> But this code worked :
>>> def con(user, mybook):
>>>     ub = UserBook()
>>>     ub.book = mybook
>>>     ub.user = user
>>>     user.reads.append(ub)
>>>     session.commit()
>> 
>>> Why the first one is not working?
>> 
>> It's not certain without a full example + stack trace, however often this 
>> occurs because of autoflush (perhaps when user.reads hits the DB to load 
>> itself first).  The stack trace would illustrate if the integrity error is 
>> due to a premature autoflush (you'd see _autoflush() in the trace), and 
>> there are ways to get around that issue.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to