I'm not using the recipe, so I could be completely wrong about this, but here goes:
The EntitySingleton metaclass stores already-constructed instances in a class-level WeakValueDictionary attribute. This will be shared between threads. When you create your UniqueName object, it looks in that WeakValueDictionary, finds the existing instance and returns it, even though it may have been created in a different thread and attached to a different session. I don't think the EntitySingleton is thread-safe. I don't know how best to fix it. You really want the instances to be associated with their session. You could try replacing the first line of __call__ with: hashkey = (ctx.current, name) ...but I don't know whether that could have any undesired side-effects. Note that your UniqueName objects will only be unique within the current session, but that may be OK for your purposes. Hope that helps, Simon -----Original Message----- From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED] On Behalf Of kris Sent: 15 June 2007 21:29 To: sqlalchemy Subject: [sqlalchemy] UniqueObject recipe and turbogears I have been trying to use the unique object recipe ( http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject ) with turbogears, but have run in to trouble. In a nut shell sqlalchemy complains that a UniqueName object is attached in multiple sessions and throws an exception. I am not sure if the recipe plays nicely with assign_mapper, or the other extensions. I am not using activemapper though TG does bring it into the picture. For reference I have posted the error I am seeing. This comes in many forms, but generally the same. The key lines below are the creation, the unique object during creation the creation of another database object. 2007-06-15 12:04:26,849 cherrypy.msg INFO HTTP: Page handler: <bound method GObjectResource.default of <bisquik.resource.gobject_resource.GObjectResource object at 0x1b8d6d0>> Traceback (most recent call last): File "/var/lib/python-support/python2.4/cherrypy/_cphttptools.py", line 105, in _run self.main() File "/var/lib/python-support/python2.4/cherrypy/_cphttptools.py", line 254, in main body = page_handler(*virtual_path, **self.params) File "<string>", line 3, in default File "/var/lib/python-support/python2.4/turbogears/controllers.py", line 334, in expose output = database.run_with_transaction( File "<string>", line 5, in run_with_transaction File "/var/lib/python-support/python2.4/turbogears/database.py", line 302, in so_rwt retval = func(*args, **kw) File "<string>", line 5, in _expose File "/var/lib/python-support/python2.4/turbogears/controllers.py", line 351, in <lambda> mapping, fragment, args, kw))) File "/var/lib/python-support/python2.4/turbogears/controllers.py", line 378, in _execute_func output = errorhandling.try_call(func, *args, **kw) File "/var/lib/python-support/python2.4/turbogears/ errorhandling.py", line 73, in try_call return func(self, *args, **kw) File "/home/kgk/work/bisquik/development/TG/bisquik/resource/ resource.py", line 152, in default response = method(resource, doc=xmldoc, **kw) File "<string>", line 3, in modify File "/var/lib/python-support/python2.4/turbogears/controllers.py", line 330, in expose output = func._expose(func, accept, func._allow_json, File "<string>", line 5, in _expose File "/var/lib/python-support/python2.4/turbogears/controllers.py", line 351, in <lambda> mapping, fragment, args, kw))) File "/var/lib/python-support/python2.4/turbogears/controllers.py", line 378, in _execute_func output = errorhandling.try_call(func, *args, **kw) File "/var/lib/python-support/python2.4/turbogears/ errorhandling.py", line 73, in try_call return func(self, *args, **kw) File "/home/kgk/work/bisquik/development/TG/bisquik/resource/ gobject_resource.py", line 144, in modify request = tagparser.parseDoc (txt) File "/home/kgk/work/bisquik/development/TG/bisquik/resource/ tagparser.py", line 169, in parseDoc parseString (doc, handler) File "/usr/lib/python2.4/site-packages/_xmlplus/sax/__init__.py", line 47, in parseString parser.parse(inpsrc) File "/usr/lib/python2.4/site-packages/_xmlplus/sax/expatreader.py", line 109, in parse xmlreader.IncrementalParser.parse(self, source) File "/usr/lib/python2.4/site-packages/_xmlplus/sax/xmlreader.py", line 123, in parse self.feed(buffer) File "/usr/lib/python2.4/site-packages/_xmlplus/sax/expatreader.py", line 216, in feed self._parser.Parse(data, isFinal) File "/usr/lib/python2.4/site-packages/_xmlplus/sax/expatreader.py", line 312, in start_element self._cont_handler.startElement(name, AttributesImpl(attrs)) File "/home/kgk/work/bisquik/development/TG/bisquik/resource/ tagparser.py", line 80, in startElement node = GObject() File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/mapper.py", line 672, in init oldinit(self, *args, **kwargs) File "/home/kgk/work/bisquik/development/TG/bisquik/model/ tag_model.py", line 480, in __init__ self.table = 'gobjects' File "/home/kgk/work/bisquik/development/TG/bisquik/model/ tag_model.py", line 317, in settable self.dbtable = UniqueName(v) File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ attributes.py", line 45, in __set__ self.set(None, obj, value) File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ attributes.py", line 280, in set ext.set(event or self, obj, value, old) File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ unitofwork.py", line 63, in set sess.save_or_update(newvalue, entity_name=ename) File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/session.py", line 398, in save_or_update self._save_or_update_impl(object, entity_name=entity_name) File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/session.py", line 406, in _save_or_update_impl self._update_impl(object, entity_name=entity_name) File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/session.py", line 527, in _update_impl self._attach(object) File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/session.py", line 547, in _attach raise exceptions.InvalidRequestError("Object '%s' is already attached to session '%s' (this is '%s')" % (repr(obj), old, id(self))) InvalidRequestError: Object 'UniqueName(gobjects)' is already attached to session '36214608' (this is '34595088') --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---