On Dec 28, 2007, at 4:20 AM, Max Ischenko wrote:
> class DatabaseFacade(object): > ... > session = property(fget=lambda self: Session()) > > Session is setup as: > Session = scoped_session(sessionmaker(autoflush=True, > transactional=True)) > > and configured later on. > > Here is how I use it: > > def create_draft(self, **kw): > p = WordpressPost(**kw) > self.session.save(p) > self.session.commit() > return p > > Since self.session is a property it calls Session() repeatedly. It > seems to work but is it OK, from transactional/performance point of > view? since Session is scoped, its automatically a threadlocal. you could just say: class DatabaseFacade(object): session = Session the transaction "commit" inside the create_draft method is a little strange. usually, if you have a long running transaction, there would be a begin()/commit() pair framing a series of operations. issuing commits inside of method sets seems to imply you dont really want a "transactional" session....but the session begins the next transaction lazily so theres probably nothing terrible about doing it that way. > Do I need to change it to something like: > s = self.session # obtain new session > s.save(p) > s.commit() > nah, with scoped_session you really arent using a "new" session in any case, its all the same underlying session object bound to the thread. you only get a "new" session if you were to first say Session.remove(). > I also noticed that session.save() fails if I try to save a > "persistent" object so I am forced to change every such save() call > to save_or_update(). I don't mind but why it's not mentioned in > whatsnew40/migration guide? well that has always been the rule, it was just never enforced...that was a new change in 0.4.1. the stricter session behavior is mentioned in the 0.4.1 CHANGES. > Another error I am now getting is: > InvalidRequestError: Instance '[EMAIL PROTECTED]' is with key > (<class 'doupy.model.objects.Invoice'>, (73L,), None) already > persisted with a different identity > > Any ideas how to fix this? it depends on how you are getting there. it means there is already an Invoice object with the same _instance_key in the session. to create this error, do this: s1 = create_session() s2 = create_session() obj1 = s1.query(MyClass).get(1) obj2 = s2.query(MyClass).get(2) s1.expunge(obj1) s2.update(obj1) # <-- error or more low level, you could do it like this: s1 = create_session() obj1 = s1.query(MyClass).get(1) obj2 = MyClass() obj2._instance_key = obj1 s1.update(obj2) note that if you are using scoped_session, you have a distinct session per application thread. so if any sharing of data between threads is going on, that makes an error like this fairly easy to produce (i.e. things can be updated() into the session via cascades along a relation(), for example). > Btw, is it possible to retrieve metadata if you have an engine or > configured session object? I haven't found a way so ended up storing > it in a module global when session is configured. MetaData is usually a module global, its attached to tables also....so for example class_mapper(AnyMappedClass).mapped_table.metadata --~--~---------~--~----~------------~-------~--~----~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---