2014-04-28 40 views
0

我有一個代碼段:爲什麼psycopg2佔位符在不同的Linux機器上的行爲不同?

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是BIT(160)型

在Ubuntu(14.04,Python的2.7.6,psycopg(2.5.2),postgres的(9.3))它的工作原理如預期。佔位符擴展爲帶引號的字符串,x「'字面值允許將該字符串視爲postgres可以放入BIT(160)字段的十六進制值。

但是在CentOS(6.5,Python的2.7.6編譯來源,psycopg(2.5.2),Postgres的(9.3))psycopg增加Ë引用之前的字符串,這意味着它的轉義字符串,我得到回溯

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

如何避免添加E?我用psycopg2.estensions.AsIs:

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

但我有用不了兩年時間,以SELECT xd57789a80870ccc0c6d65b5a844091a06e6850...中沒有報價,導致錯誤xd57789a80870ccc0c6d65b5a844091a06e6850列不存在SQL語句。

我也試過

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

但逃避字面ê再次出現。

是否有任何優雅的,這個問題的portale解決方案?

回答

1

不同的是,您的CentOS機器上可能有standard_conforming_strings設置爲offhttp://www.postgresql.org/docs/9.3/static/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS

因此,將其設置爲on將解決您的問題,因爲psycopg不會在字符串前添加E. 如果你確實需要關閉它,你可能會將你的十六進制轉換爲Python中的一個160字節的'1011 ...'字符串,並使用SELECT %s::bit(160), %s來代替,但那很糟糕。

+0

這解決了我的問題。謝謝!我想知道你是如何找到這個解決方案的。 :)我的CentOS似乎有舊的postgres.conf,因爲股票postgres版本是8.x,並且它是手動升級的。 – omikron

+0

那麼,psycopg2源代碼中的E'grep,以及psycopg/connection_int.c中的外觀以及一些測試解決了它=) –

相關問題