2017-07-27 51 views
0

我想一个UTF8字符串从蟒蛇通过cx_oracle保存到Oracle数据库和失败Python可以UTF-8不能保存到Oracle

这里是一个具有特殊吨它的字符串: “斯特拉达恩·图克莱斯卡20,罗马尼亚Craiova”

这里是DB配置:

PARAMETER      VALUE         
------------------------------ ---------------------------------------- 
NLS_CHARACTERSET    EE8ISO8859P2        
NLS_NCHAR_CHARACTERSET   AL16UTF16 

该表具有类型的目标列NVARCHAR2

在Python中我做的:

os.environ['NLS_LANG'] = '.AL32UTF8' 
cur.setinputsizes(cx_Oracle.NCHAR, cx_Oracle.NCHAR) 
cur.executemany('update table set var=:var where ID_=:ID_', values) 

而且我仍然得到'?'而不是那个特殊的'T'。

我在做什么错?

+0

数据类型为“NVARCHAR2”的列“var”? (不是'VARCHAR2') –

+0

是的,我在问题 – snovik

+0

中写了它你用'SELECT DUMP(VAR,1016)FROM TABLE得到了什么?''也许这只是你终端的显示问题。 –

回答

0

我不知道是否有帮助,但我写了一个小的PL/SQL程序,找出不匹配:

DECLARE 
    --sourceChar VARCHAR2(10) := 'U+21A'; 
    --sourceChar VARCHAR2(10) := 'U+E2'; 
    sourceChar VARCHAR2(10) := 'Ț'; 

    codepoint INTEGER; 
    sg1 VARCHAR2(6); 
    sg2 VARCHAR2(4); 

    CURSOR CharacterSets IS 
    SELECT VALUE, UTL_I18N.MAP_CHARSET(VALUE) AS IANA_VALUE 
    FROM V$NLS_VALID_VALUES 
    WHERE parameter = 'CHARACTERSET' 
     AND REGEXP_LIKE(UTL_I18N.MAP_CHARSET(VALUE), 'UTF|ISO-8859|WINDOWS') 
    ORDER BY IANA_VALUE, VALUE; 

    CURSOR ClientCharacterSets IS 
    SELECT VALUE, UTL_I18N.MAP_CHARSET(VALUE) AS IANA_VALUE 
    FROM V$NLS_VALID_VALUES 
    WHERE parameter = 'CHARACTERSET' 
     AND REGEXP_LIKE(UTL_I18N.MAP_CHARSET(VALUE), 'UTF|ISO-8859|WINDOWS') 
    ORDER BY IANA_VALUE, VALUE; 

BEGIN 
    IF REGEXP_LIKE(sourceChar, '^U\+[[:xdigit:]]+$') THEN 
     codepoint := TO_NUMBER(REGEXP_REPLACE(sourceChar, '^U\+'), 'fmXXXXX'); 
     IF codepoint <= 65535 THEN 
      sourceChar := UNISTR('\'||LPAD(TO_CHAR(codepoint, 'fmXXXXX'), 4, '0')); 
     ELSE 
      sg1 := TO_CHAR(TO_NUMBER('D800', 'XXXX') + TRUNC((codepoint - 2**16)/2**10), 'fmXXXX'); 
      sg2 := TO_CHAR(TO_NUMBER('DC00', 'XXXX') + (codepoint - 2**16) MOD 2**10, 'fmXXXX'); 
      sourceChar := UNISTR('\'||LPAD(sg1, 4, '0')||'\'||LPAD(sg2, 4, '0')); 
     END IF; 
    ELSE  
     IF REGEXP_LIKE(ASCIISTR(sourceChar), '^\\[[:xdigit:]]+$') THEN 
      codepoint := TO_NUMBER(REGEXP_REPLACE(ASCIISTR(sourceChar), '^\\'), 'XXXXX'); 
     ELSIF REGEXP_LIKE(ASCIISTR(sourceChar), '^\\[[:xdigit:]]+\\[[:xdigit:]]+$') THEN 
      sg1 := REGEXP_SUBSTR(ASCIISTR(sourceChar), '[[:xdigit:]]+'); 
      sg2 := REGEXP_SUBSTR(ASCIISTR(sourceChar), '[[:xdigit:]]+', 1, 2); 
      codepoint := 2**10 * (TO_NUMBER(sg1, 'XXXXX') - TO_NUMBER('D800', 'XXXX') + 2**6) + TO_NUMBER(sg2, 'XXXX') - TO_NUMBER('DC00', 'XXXX');  
     ELSE 
      codepoint := ASCII(sourceChar); 
     END IF; 
    END IF; 
    DBMS_OUTPUT.PUT_LINE (sourceChar || ' -> U+' || TO_CHAR(codepoint, 'fmXXXXX')); 

    DBMS_OUTPUT.PUT('Character Set'||CHR(9)||'Char'); 
    FOR aSet IN ClientCharacterSets LOOP 
     DBMS_OUTPUT.PUT(CHR(9)|| aSet.VALUE); 
    END LOOP; 
    DBMS_OUTPUT.NEW_LINE(); 

    FOR aSrcSet IN CharacterSets LOOP 
     DBMS_OUTPUT.PUT(aSrcSet.VALUE ||CHR(9)|| '0x'||RAWTOHEX(UTL_I18N.STRING_TO_RAW(sourceChar, aSrcSet.VALUE))); 
     FOR aClientSet IN ClientCharacterSets LOOP 
      IF aSrcSet.VALUE = aClientSet.VALUE THEN 
       DBMS_OUTPUT.PUT(CHR(9)|| aSrcSet.VALUE); 
      ELSIF UTL_I18N.RAW_TO_CHAR(UTL_I18N.STRING_TO_RAW(sourceChar, aSrcSet.VALUE), aClientSet.VALUE) = sourceChar THEN 
       DBMS_OUTPUT.PUT(CHR(9)|| 'Match'); 
      ELSE 
       DBMS_OUTPUT.PUT(CHR(9)|| UTL_I18N.RAW_TO_CHAR(UTL_I18N.STRING_TO_RAW(sourceChar, aSrcSet.VALUE), aClientSet.VALUE)); 
      END IF; 
     END LOOP; 
     DBMS_OUTPUT.NEW_LINE(); 
    END LOOP; 
END; 

对于Ț

Ț -> U+21A 
Character Set Char WE8ISO8859P1 NE8ISO8859P10 BLT8ISO8859P13 CEL8ISO8859P14 WE8ISO8859P15 EE8ISO8859P2 SE8ISO8859P3 NEE8ISO8859P4 CL8ISO8859P5 AR8ISO8859P6 EL8ISO8859P7 IW8ISO8859P8 WE8ISO8859P9 AL16UTF16 AL32UTF8 UTF8 EE8MSWIN1250 CL8MSWIN1251 WE8MSWIN1252 EL8MSWIN1253 TR8MSWIN1254 IW8MSWIN1255 AR8MSWIN1256 BLT8MSWIN1257 VN8MSWIN1258 
WE8ISO8859P1 0xBF WE8ISO8859P1 ŋ æ ṡ ¿ ż ż ŋ П ؟ Ώ � ¿   � ż ї ¿ Ώ ¿ ¿ ؟ æ ¿ 
NE8ISO8859P10 0x3F ? NE8ISO8859P10 ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
BLT8ISO8859P13 0x3F ? ? BLT8ISO8859P13 ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
CEL8ISO8859P14 0x3F ? ? ? CEL8ISO8859P14 ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
WE8ISO8859P15 0xBF ¿ ŋ æ ṡ WE8ISO8859P15 ż ż ŋ П ؟ Ώ � ¿   � ż ї ¿ Ώ ¿ ¿ ؟ æ ¿ 
EE8ISO8859P2 0x3F ? ? ? ? ? EE8ISO8859P2 ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
SE8ISO8859P3 0x3F ? ? ? ? ? ? SE8ISO8859P3 ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
NEE8ISO8859P4 0x3F ? ? ? ? ? ? ? NEE8ISO8859P4 ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
CL8ISO8859P5 0x3F ? ? ? ? ? ? ? ? CL8ISO8859P5 ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
AR8ISO8859P6 0x3F ? ? ? ? ? ? ? ? ? AR8ISO8859P6 ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
EL8ISO8859P7 0x3F ? ? ? ? ? ? ? ? ? ? EL8ISO8859P7 ? ?  ? ? ? ? ? ? ? ? ? ? ? 
IW8ISO8859P8 0x3F ? ? ? ? ? ? ? ? ? ? ? IW8ISO8859P8 ?  ? ? ? ? ? ? ? ? ? ? ? 
WE8ISO8859P9 0x3F ? ? ? ? ? ? ? ? ? ? ? ? WE8ISO8859P9  ? ? ? ? ? ? ? ? ? ? ? 
AL16UTF16 0x021A              AL16UTF16           
AL32UTF8 0xC89A È Č Č È È Č È Č Ш ب Θ � È 좚 AL32UTF8 Match Čš Иљ Èš Θ Èš ָ بڑ Č È 
UTF8 0xC89A È Č Č È È Č È Č Ш ب Θ � È 좚 Match UTF8 Čš Иљ Èš Θ Èš ָ بڑ Č È 
EE8MSWIN1250 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? EE8MSWIN1250 ? ? ? ? ? ? ? ? 
CL8MSWIN1251 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? CL8MSWIN1251 ? ? ? ? ? ? ? 
WE8MSWIN1252 0xBF ¿ ŋ æ ṡ ¿ ż ż ŋ П ؟ Ώ � ¿   � ż ї WE8MSWIN1252 Ώ ¿ ¿ ؟ æ ¿ 
EL8MSWIN1253 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? EL8MSWIN1253 ? ? ? ? ? 
TR8MSWIN1254 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? TR8MSWIN1254 ? ? ? ? 
IW8MSWIN1255 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? IW8MSWIN1255 ? ? ? 
AR8MSWIN1256 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? AR8MSWIN1256 ? ? 
BLT8MSWIN1257 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? BLT8MSWIN1257 ? 
VN8MSWIN1258 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? VN8MSWIN1258 

对于â

â -> U+E2 
Character Set Char WE8ISO8859P1 NE8ISO8859P10 BLT8ISO8859P13 CEL8ISO8859P14 WE8ISO8859P15 EE8ISO8859P2 SE8ISO8859P3 NEE8ISO8859P4 CL8ISO8859P5 AR8ISO8859P6 EL8ISO8859P7 IW8ISO8859P8 WE8ISO8859P9 AL16UTF16 AL32UTF8 UTF8 EE8MSWIN1250 CL8MSWIN1251 WE8MSWIN1252 EL8MSWIN1253 TR8MSWIN1254 IW8MSWIN1255 AR8MSWIN1256 BLT8MSWIN1257 VN8MSWIN1258 
WE8ISO8859P1 0xE2 WE8ISO8859P1 Match ā Match Match Match Match Match т ق β ג Match    Match в Match β Match ג Match ā Match 
NE8ISO8859P10 0xE2 Match NE8ISO8859P10 ā Match Match Match Match Match т ق β ג Match    Match в Match β Match ג Match ā Match 
BLT8ISO8859P13 0x3F ? ? BLT8ISO8859P13 ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
CEL8ISO8859P14 0xE2 Match Match ā CEL8ISO8859P14 Match Match Match Match т ق β ג Match    Match в Match β Match ג Match ā Match 
WE8ISO8859P15 0xE2 Match Match ā Match WE8ISO8859P15 Match Match Match т ق β ג Match    Match в Match β Match ג Match ā Match 
EE8ISO8859P2 0xE2 Match Match ā Match Match EE8ISO8859P2 Match Match т ق β ג Match    Match в Match β Match ג Match ā Match 
SE8ISO8859P3 0xE2 Match Match ā Match Match Match SE8ISO8859P3 Match т ق β ג Match    Match в Match β Match ג Match ā Match 
NEE8ISO8859P4 0xE2 Match Match ā Match Match Match Match NEE8ISO8859P4 т ق β ג Match    Match в Match β Match ג Match ā Match 
CL8ISO8859P5 0x3F ? ? ? ? ? ? ? ? CL8ISO8859P5 ? ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
AR8ISO8859P6 0x3F ? ? ? ? ? ? ? ? ? AR8ISO8859P6 ? ? ?  ? ? ? ? ? ? ? ? ? ? ? 
EL8ISO8859P7 0x3F ? ? ? ? ? ? ? ? ? ? EL8ISO8859P7 ? ?  ? ? ? ? ? ? ? ? ? ? ? 
IW8ISO8859P8 0x3F ? ? ? ? ? ? ? ? ? ? ? IW8ISO8859P8 ?  ? ? ? ? ? ? ? ? ? ? ? 
WE8ISO8859P9 0xE2 Match Match ā Match Match Match Match Match т ق β ג WE8ISO8859P9    Match в Match β Match ג Match ā Match 
AL16UTF16 0x00E2 â â ā â â â â â т ق β ג â AL16UTF16   â в â β â ג â ā â 
AL32UTF8 0xC3A2 â ÃĒ Ć¢ Ãḃ â â �˘ Ãĸ УЂ أ� Γ’ �¢ â 쎢 AL32UTF8 Match â Гў â ΓΆ â ֳ¢ أ¢ Ć¢ Ă¢ 
UTF8 0xC3A2 â ÃĒ Ć¢ Ãḃ â â �˘ Ãĸ УЂ أ� Γ’ �¢ â 쎢 Match UTF8 â Гў â ΓΆ â ֳ¢ أ¢ Ć¢ Ă¢ 
EE8MSWIN1250 0xE2 Match Match ā Match Match Match Match Match т ق β ג Match    EE8MSWIN1250 в Match β Match ג Match ā Match 
CL8MSWIN1251 0x61 a a a a a a a a a a a a a  a a a CL8MSWIN1251 a a a a a a a 
WE8MSWIN1252 0xE2 Match Match ā Match Match Match Match Match т ق β ג Match    Match в WE8MSWIN1252 β Match ג Match ā Match 
EL8MSWIN1253 0x61 a a a a a a a a a a a a a  a a a a a EL8MSWIN1253 a a a a a 
TR8MSWIN1254 0xE2 Match Match ā Match Match Match Match Match т ق β ג Match    Match в Match β TR8MSWIN1254 ג Match ā Match 
IW8MSWIN1255 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? IW8MSWIN1255 ? ? ? 
AR8MSWIN1256 0xE2 Match Match ā Match Match Match Match Match т ق β ג Match    Match в Match β Match ג AR8MSWIN1256 ā Match 
BLT8MSWIN1257 0x3F ? ? ? ? ? ? ? ? ? ? ? ? ?  ? ? ? ? ? ? ? ? ? BLT8MSWIN1257 ? 
VN8MSWIN1258 0xE2 Match Match ā Match Match Match Match Match т ق β ג Match    Match в Match β Match ג Match ā VN8MSWIN1258 

您看到â比0123更匹配,即在许多字符集中比特值是相同的。尝试更多的字符,也许你会发现python使用哪些字符集,以及如何设置它。

0

这是忽略其余部分的代码的主要部分。我正在使用python3,oracle部分在windows7上运行

if args.proxy_pwd is not None: 
    print('Setting proxy...') 
    set_proxy(args.proxy_pwd) 

if args.db_pwd is None:  # reading from csv file 
    print('Reading sourcefile...') 
    df = pd.read_csv(params[args.source][0], sep = ';') 
else:      # reading from db 
    print('Reading db...') 

    import cx_Oracle 
    con = cx_Oracle.connect(args.db_usr, args.db_pwd, args.db_type) 
    df = pd.read_sql_query('''select * from geo_poi 
           where geo_status is Null and rownum < 3000''', 
          con) 

    #print(df) 

df = update_geo(df, params[args.source][1]) # query google api 

# save results 
print('Saving...') 
if args.db_pwd is None: # to csv 
    df.to_csv(params[args.source][0], index=False, sep = ';') 
else:     # to db 
    df = df[df['GEO_STATUS'].notnull()]  # save only geocoded results 

    columns = ['GEO_STATUS', 'GEO_ADDRESS', 'GEO_POSTCODE', 
       'GEO_TYPE', 'GEO_LATITUDE', 'GEO_LONGITUDE', 
       'GEO_ACCURACY', 'GEO_GOOGLE_ID', 'GEO_NUMBER_OF_RESULTS', 
       'TYPE_', 'ID_'] 
    values = [[df.loc[i, j] for j in columns] for i in range(len(df))] 
    #print(values) 

    cur = con.cursor() 
    cur.executemany('''update geo_poi 
         set GEO_STATUS=:GEO_STATUS, GEO_ADDRESS=:GEO_ADDRESS, 
          GEO_POSTCODE=:GEO_POSTCODE, GEO_TYPE=:GEO_TYPE, 
          GEO_LATITUDE=:GEO_LATITUDE, GEO_LONGITUDE=:GEO_LONGITUDE, 
          GEO_ACCURACY=:GEO_ACCURACY, GEO_GOOGLE_ID=:GEO_GOOGLE_ID, 
          GEO_NUMBER_OF_RESULTS=:GEO_NUMBER_OF_RESULTS 
         where TYPE_=:TYPE_ and ID_=:ID_''', 
        values) 
    con.commit()