Yeah... the closing thing is because this is going to be in a
webserver, and the framework that controls the requests really, really
messed up everything (mysql daemon, sqlalchemy...) if the http request
was canceled (If I had a user pressing F5 in Firefox all the time, I
got coredumps that stopped the server)

That was me: 
http://groups.google.com/group/sqlalchemy/browse_thread/thread/5a3c7c8056cf6a60/6805bbe38667b9be?lnk=gst&q=Hector+Blanco#6805bbe38667b9be

That's why I decided to commit, close, and such as soon as possible
(leave the sessions opened as little as possible)

The problem seems to have improved lately (there was an update of the
Zope framework recently, and the problem seems to have "relaxed" a
bit)... but I'm still scared!! According to some other documents/posts
I've read, maybe a commit (without the closing) would still work,
though.

2011/3/23 Michael Bayer <mike...@zzzcomputing.com>:
> There's a lot of detail here but the antipattern I see is you're creating a 
> session just to do a getById() then closing it.    A single Session should 
> frame a logical series of operations.  When those operations are complete, 
> you commit your session if needed, close it out, then throw everything away.  
>  Using detached objects is only when moving them in and out of a cache or 
> passing them across thread or process boundaries to another waiting worker 
> that will immediately re-merge them back into a different Session, which is 
> itself framing out a logical series of operations.
>
>
> On Mar 23, 2011, at 2:48 PM, Hector Blanco wrote:
>
>> Hello everyone...
>>
>> I am getting detached instances error and I don't really know why.
>> There's something I don't get with the session, but I have been
>> reading the documentation thoroughly, trying many things and I can't
>> get rid of all the DetachedInstance exceptions... That's why I think
>> I'm doing something [deeply] wrong ( I think I have a core "concept
>> error")
>>
>> I have designed my application in the following way:
>>
>> The idea is to have my mapped classes (classes serialized in a MySQL
>> table) and for each class  I would have a "manager" that contains a
>> bunch of methods that deal with the database.
>>
>> Let's say I have:
>>
>> class Foo(Database.Base):
>>       _id = Column("id", Integer, primary_key=True, key="id")
>>       _name = Column("name", String(50))
>>
>> Then I will also have a "FooManager" like this:
>>
>> ----------------------------------------
>> from myLibraries.foos import Foo
>>
>> class FooManager(object):
>>
>>       @classmethod
>>       def getById(cls, idParam, relationshipsToPreLoad=None):
>>               retval = None
>>               if relationshipsToPreLoad is None:
>>                       relationshipsToPreLoad = 
>> DatabaseUtils.getRelationships(Foo.Foo)
>>               session = Database.Session()
>>               try:
>>                       if (relationshipsToPreLoad):
>>                               retval = session.query(Foo.Foo).options(*
>> [joinedload_all(relationshipToPreLoad)
>>                                               for relationshipToPreLoad in
>> relationshipsToPreLoad]).get(int(idParam))
>>                       else:
>>                               retval = 
>> session.query(Foo.Foo).get(int(idParam))
>>                       session.commit()
>>               except exc.ResourceClosedError, err:
>>                       log.debug('::getById > Manager %s > Got exception 
>> "%s".\
>>                                       Probably the request was canceled by 
>> the user' % (cls.__name__, err))
>>               finally:
>>                       session.close()
>>                       pass
>>               return retval
>>
>>       @classmethod
>>       def update(cls, element):
>>               if isinstance(element, Foo.Foo):
>>                       session = Database.Session()
>>                       try:
>>                               element = session.merge(element)
>>                               session.commit()
>>                       finally:
>>                               session.close()
>>                               log.debug("::update> Updated %s with id==%s" %
>> (element.__class__.__name__, element.id))
>>                               return element
>>               else:
>>                       raise TypeError("Received parameter %s of type %s when 
>> expecting
>> %s" % (element, type(element), Foo.Foo.__classname__))
>>                       return None
>> ----------------------------------------
>>
>> So when, in another part of the application I want to load the element
>> Foo.Foo with id 6, I could just do:
>>
>> myFooInstance = myLibraries.foos.FooManager.FooManager.getById(6)
>> print myFooInstance.id
>> print myFooInstance.name
>>
>> Or, if I create a new Foo instance, I can do:
>> newFoo = Foo.Foo()
>> newFoo.name = "fooname"
>> myLibraries.foos.FooManager.FooManager.update(newFoo)
>>
>> and the "newFoo" will be added to the database.
>>
>> The "Database" module is just a few lines long and contains the session 
>> maker:
>>
>> ---- Database.py -----
>> DSN = "mysql://mysqluser:*******@localhost/ev?charset=utf8"
>> engine = create_engine(DSN)
>> Session = scoped_session(sessionmaker(bind=engine))
>>
>> Base = declarative_base()
>> -----------------------------------------------
>>
>>
>> The whole idea is separating the access to the database from the
>> classes itself (the manager's idea is something like "go to the
>> database, do your thing, give me a regular python class", but it's not
>> working fine. I've been able to find some workarounds but it's still
>> not working fine. Do you think this "Class/ ClassManager" type of
>> implementation a good idea? As you can see, in every method of the
>> manager I create a new instance of the session, do whatever and close
>> it. Is that the way the session is supposed to be used? Should the
>> session be global? (I can create an instance in Database.py)
>>
>> I saw this:
>> http://groups.google.com/group/sqlalchemy/browse_thread/thread/f53f98cbbaee7b2b/14c3d8c7229ba0bc?lnk=gst&q=DetachedInstanceError#14c3d8c7229ba0bc
>>
>> which seems to detail a similar problem. I tried both methods detailed
>> there, but I'm still getting detached instances errors. And it seems
>> to me that it recommends not to use detached instances (which, as far
>> as I understand, is what I'm trying to do here)
>>
>> Any hint will be deeply appreciated. Thank you everyone!
>>
>> --
>> 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.
>
>

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