Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataError when underlying type changes #183

Closed
psycoteam opened this issue Oct 11, 2013 · 4 comments
Closed

DataError when underlying type changes #183

psycoteam opened this issue Oct 11, 2013 · 4 comments
Labels

Comments

@psycoteam
Copy link

Originally 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:

gratipay/gratipay.com#1583

@dvarrazzo
Copy link
Member

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.

@psycoteam
Copy link
Author

Originally submitted by: Chad Whitacre

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?

@dvarrazzo
Copy link
Member

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.

@psycoteam
Copy link
Author

Originally submitted by: Chad Whitacre

Sounds sensible. Thanks Daniele! :-)

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants