This project is archived and is in readonly mode.

#183 ✓invalid
Psycopg website

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:

https://github.com/gittip/www.gittip.com/issues/1583

Comments and changes to this ticket

  • Daniele Varrazzo

    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

    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 of DataError in CompositeCaster.parse instead of DataError itself? That way our application could catch that (without swallowing other, unrelated DataErrors) and then retry register_composite or take other measures. Would this be acceptable to you?

  • Daniele Varrazzo

    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.

  • Chad Whitacre

    Chad Whitacre October 14th, 2013 @ 09:04 PM

    Sounds sensible. Thanks Daniele! :-)

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.

Shared Ticket Bins

Tags

Pages