This project is archived and is in readonly mode.
DataError when underlying type changes
Reported by Psycopg website | October 11th, 2013 @ 06:48 PM
Submitted by: Chad Whitacre (whit537)
psycopg2 caches the attributes of composite types, so that when the type is altered in the database, the next attempt to cast that type in psycopg2 results in a DataError. This seems to introduce a race condition between modifying the database and restarting processes accessing the database.
More information:
Comments and changes to this ticket
-
Daniele Varrazzo October 11th, 2013 @ 10:41 PM
- State changed from new to invalid
Caching of the attribute is necessary but it's local to the scope you have registered the composite.
Avoid using register_composite with global=True: use it on the connection or on the cursor, and dispose the connection or the cursor after the data type is changed. Alternatively just call register_composite again.
-
Chad Whitacre October 12th, 2013 @ 02:13 AM
Thanks @dvarrazzo. Scoping our
register_composite
calls to the connection or cursor would narrow the race condition, but wouldn't eliminate it. I'm not sure we can eliminate it, though, so what would you think of raising a subclass ofDataError
inCompositeCaster.parse
instead ofDataError
itself? That way our application could catch that (without swallowing other, unrelatedDataError
s) and then retryregister_composite
or take other measures. Would this be acceptable to you? -
Daniele Varrazzo October 14th, 2013 @ 11:15 AM
Hello Chad,
the use case for such subclass is fairly restricted, and I think it would be more the hassle to document it than its general usefulness, not to mention that people is usually unhappy to get a new feature in rel. 2.5.2.
So my suggestion is you make your own subclass of the adapter, which should be something as easy as (untested):
class CompositeChanged(DataError): pass class OurCompositeCaster(CompositeCaster): def parse(self, s, curs): try: return super(OurCompositeCaster, self).parse(s, curs) except DataError, e: raise CompositeChanged(str(e))
this should do everything you need.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป
<b>WARNING:</b> the informations in this tracker are archived. Please submit new tickets or comments to <a href="https://github.com/psycopg/psycopg2/issues">the new tracker</a>.
<br/>
Psycopg is the most used PostgreSQL adapter for the Python programming language. At the core it fully implements the Python DB API 2.0 specifications. Several extensions allow access to many of the features offered by PostgreSQL.