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

Reply via email to