Question

I have a code snippet:

hashed = hashlib.sha1(some_value).hexdigest()
insert = """
    INSERT INTO dimensions_hash (dimensions_hash_id, dimensions_string)
    SELECT x%s, %s
    WHERE NOT EXISTS (
        SELECT 1
        FROM dimensions_hash
        WHERE
            dimensions_hash_id = x%s
    );
"""
cursor.execute(insert, [hashed, some_value, hashed])

dimensions_hash_id is BIT(160) type

On Ubuntu (14.04, Python 2.7.6, psycopg (2.5.2), postgres (9.3)) it works as expected. Placeholder is expanded to quoted string, x'' literal allows to treat this string as hexadecimal value which postgres can fit into BIT(160) field.

However on CentOS (6.5, Python 2.7.6 build from sources, psycopg (2.5.2), postgres (9.3)) psycopg adds E before quoted string which means it's escaped string and I'm getting traceback

ProgrammingError: type "xe" does not exist
LINE 3:             SELECT xE'd57789a80870ccc0c6d65b5a844091a06e6850...

How to avoid adding E? I used psycopg2.estensions.AsIs:

from psycopg2.extensions import AsIs
#...
hashed = AsIs(hashlib.sha1(some_value).hexdigest())
#...

But I've got sql statement expaned to SELECT xd57789a80870ccc0c6d65b5a844091a06e6850... WITHOUT quote which results in error that xd57789a80870ccc0c6d65b5a844091a06e6850 column doesn't exist.

I've also tried

hashed = AsIs(hashlib.sha1(some_value).hexdigest()).getquoted()

but escape literal E appeared again.

Is there any elegant, portale solution for this problem?

Was it helpful?

Solution

The difference is probably that you have standard_conforming_strings set to off on your CentOS machine. http://www.postgresql.org/docs/9.3/static/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS

So, setting it to on will solve your problem as psycopg won't add E in front of strings. If you really need it to be off, you could probably convert your hexdigest to a 160 byte '1011...'-string in python and use SELECT %s::bit(160), %s instead, but thats rather ugly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top