繁体   English   中英

Python无法将utf-8保存到Oracle

[英]Python cannot save utf-8 to oracle

我正在尝试通过cx_oracle从python将UTF8字符串保存到oracle数据库并失败

这是其中带有特殊T的字符串:“ Strada Ion Țuculescu 20,罗马尼亚克拉约瓦”

这是数据库配置:

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”。

我究竟做错了什么?

我不知道是否有帮助,但是我写了一个小的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

您会发现âȚ具有更多的匹配项,即,在许多字符集中,位值都是相同的。 再尝试一些字符,也许您会发现python使用哪个字符集以及如何设置它。

这是代码的主要部分,忽略了其余部分。 我正在使用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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM